From fe84bd41093f1908cedc64d0257670dec94bbc9a Mon Sep 17 00:00:00 2001 From: andy Date: Thu, 16 Feb 2023 00:06:14 +0000 Subject: [PATCH 01/58] right-side text support --- src/ship/ship.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 8a1c6fa..0b188ae 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -292,6 +292,7 @@ pub enum SendShipPacket { TradeSuccessful(TradeSuccessful), LobbyEvent(LobbyEvent), LargeDialog(LargeDialog), + RightText(RightText), } impl SendServerPacket for SendShipPacket { @@ -336,6 +337,7 @@ impl SendServerPacket for SendShipPacket { SendShipPacket::TradeSuccessful(pkt) => pkt.as_bytes(), SendShipPacket::LobbyEvent(pkt) => pkt.as_bytes(), SendShipPacket::LargeDialog(pkt) => pkt.as_bytes(), + SendShipPacket::RightText(pkt) => pkt.as_bytes(), } } } -- 2.36.0 From a6a0d9c4b8f25e9b458941dfc035806f70388687 Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 18 Feb 2023 00:48:06 +0000 Subject: [PATCH 02/58] ci --- Cargo.lock | 2 -- 1 file changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c32fc6e..dfff310 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1040,7 +1040,6 @@ checksum = "739e9d7726dc32173fed2d69d17eef3c54682169e4e20ff1d0a45dcd37063cef" [[package]] name = "libpso" version = "0.1.0" -source = "git+http://git.sharnoth.com/jake/libpso#05222bbf9fe402675447bc163b45e07a327cdb1a" dependencies = [ "chrono", "psopacket", @@ -1399,7 +1398,6 @@ dependencies = [ [[package]] name = "psopacket" version = "1.0.0" -source = "git+http://git.sharnoth.com/jake/libpso#05222bbf9fe402675447bc163b45e07a327cdb1a" dependencies = [ "proc-macro2", "quote", -- 2.36.0 From 179c9010a51acf9ee1441fe2963dabb531a1b5f2 Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 18 Feb 2023 01:33:55 +0000 Subject: [PATCH 03/58] cii --- tests/test_item_pickup.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_item_pickup.rs b/tests/test_item_pickup.rs index 820e167..394cc3a 100644 --- a/tests/test_item_pickup.rs +++ b/tests/test_item_pickup.rs @@ -262,6 +262,7 @@ async fn test_pick_up_meseta_when_inventory_full() { room: 0, x: 0.0, z: 0.0, + amount: 23, })))).await.unwrap(); ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem { @@ -486,6 +487,7 @@ async fn test_can_not_drop_more_meseta_than_is_held() { room: 0, x: 0.0, z: 0.0, + amount: 301, })))).await.unwrap(); let split_attempt = ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem { @@ -604,6 +606,7 @@ async fn test_can_not_pick_up_meseta_when_full() { room: 0, x: 0.0, z: 0.0, + amount: 23, })))).await.unwrap(); ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem { @@ -658,6 +661,7 @@ async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() { room: 0, x: 0.0, z: 0.0, + amount: 23, })))).await.unwrap(); ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem { @@ -722,6 +726,7 @@ async fn test_player_drops_partial_stack_and_other_player_picks_it_up() { room: 0, x: 0.0, z: 0.0, + amount: 2, })))).await.unwrap(); ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem { -- 2.36.0 From 1ea1bbc226125e812b45b87415eaa7697befa4a1 Mon Sep 17 00:00:00 2001 From: andy Date: Sun, 12 Feb 2023 02:13:58 +0000 Subject: [PATCH 04/58] floor item limit reached --- src/entity/gateway/postgres/models.rs | 13 ++++++++++++- src/entity/item/mod.rs | 4 ++++ src/ship/items/actions.rs | 20 ++++++++++++++++++++ src/ship/items/tasks.rs | 24 ++++++++++++++++++++++++ src/ship/packet/handler/message.rs | 27 ++++++++++++++++++++++++++- src/ship/ship.rs | 4 ++++ 6 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/entity/gateway/postgres/models.rs b/src/entity/gateway/postgres/models.rs index b017b3b..81de203 100644 --- a/src/entity/gateway/postgres/models.rs +++ b/src/entity/gateway/postgres/models.rs @@ -612,6 +612,9 @@ pub enum PgItemNoteDetail { Deposit { character_id: u32, bank: BankIdentifier, + }, + FloorLimitReached { + map_area: MapArea, } } @@ -658,7 +661,12 @@ impl From for PgItemNoteDetail { character_id: character_id.0, bank, } - } + }, + ItemNote::FloorLimitReached { map_area } => { + PgItemNoteDetail::FloorLimitReached { + map_area: map_area, + } + }, } } } @@ -703,6 +711,9 @@ impl From for ItemNote { character_id: CharacterEntityId(character_id), bank, }, + PgItemNoteDetail::FloorLimitReached { map_area } => ItemNote::FloorLimitReached { + map_area: map_area, + }, } } } diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index 6b7bf53..56bf21f 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -10,6 +10,7 @@ pub mod esweapon; use serde::{Serialize, Deserialize}; use crate::entity::character::CharacterEntityId; +use crate::ship::items::ClientItemId; use crate::ship::map::MapArea; use crate::ship::drops::ItemDropType; @@ -74,6 +75,9 @@ pub enum ItemNote { character_id: CharacterEntityId, bank: BankIdentifier, }, + FloorLimitReached { + map_area: MapArea, + }, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index f9844bb..8bc3c86 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -1148,3 +1148,23 @@ where }) } } + +pub(super) fn delete_item_from_floor<'a, EG, TR>( + map_area: MapArea +) -> impl Fn((ItemStateProxy, TR), FloorItem) + -> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>> +where + EG: EntityGateway, + TR: EntityGatewayTransaction + Clone + 'a, +{ + move |(item_state, transaction), floor_item| { + Box::pin(async move { + let transaction = floor_item.with_entity_id(transaction, |mut transaction, entity_id| { + async move { + transaction.gateway().add_item_note(&entity_id, ItemNote::FloorLimitReached { map_area: map_area }).await?; + Ok(transaction) + }}).await?; + Ok(((item_state, transaction), ())) + }) + } +} \ No newline at end of file diff --git a/src/ship/items/tasks.rs b/src/ship/items/tasks.rs index 3e0cf6a..67fd179 100644 --- a/src/ship/items/tasks.rs +++ b/src/ship/items/tasks.rs @@ -508,3 +508,27 @@ where Ok((transaction, item)) }) } + +pub async fn floor_item_limit_reached<'a, EG> ( + item_state: &'a mut ItemState, + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + item_id: &'a ClientItemId, + map_area: MapArea +) -> BoxFuture<'a, Result<(), anyhow::Error>> +where + EG: EntityGateway + 'static, + EG::Transaction<'a>: Clone, +{ + entity_gateway.with_transaction(move |transaction| async move { + let item_state_proxy = ItemStateProxy::new(item_state.clone()); + let((item_state_proxy, transaction), result) = ItemStateAction::default() + .act(actions::take_item_from_floor(character.id, *item_id)) + .act(actions::delete_item_from_floor(map_area)) + .commit((item_state_proxy, transaction)) + .await?; + + item_state_proxy.commit().await; + Ok((transaction, result)) + }) +} diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index f4e4d69..c219303 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -10,7 +10,7 @@ use crate::ship::location::{ClientLocation, ClientLocationError}; use crate::ship::items::ClientItemId; use crate::ship::packet::builder; use crate::ship::items::state::ItemState; -use crate::ship::items::tasks::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item, sort_inventory, use_item, feed_mag, sell_item, take_meseta}; +use crate::ship::items::tasks::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item, sort_inventory, use_item, feed_mag, sell_item, take_meseta, floor_item_limit_reached}; pub async fn request_exp(id: ClientId, request_exp: RequestExp, @@ -500,3 +500,28 @@ where })}).await??; Ok(Vec::new()) // TODO: send the packet to other clients } + +pub async fn floor_item_limit_deletion (id: ClientId, + floor_item_limit_delete: FloorItemLimitItemDeletion, + entity_gateway: &mut EG, + client_location: &ClientLocation, + clients: &Clients, + rooms: &Rooms, + item_state: &mut ItemState) + -> Result, anyhow::Error> +where + EG: EntityGateway + Clone + 'static, +{ + let room_id = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() })?; + let map_area = rooms.with(room_id, |room| Box::pin(async move { + room.map_areas.get_area_map(floor_item_limit_delete.map_area) + })).await??; + + clients.with(id, |client| { + let mut entity_gateway = entity_gateway.clone(); + let mut item_state = item_state.clone(); + Box::pin(async move { + floor_item_limit_reached(&mut item_state, &mut entity_gateway, &client.character, &ClientItemId(floor_item_limit_delete.item_id), map_area).await + })}).await??; + Ok(Vec::new()) +} \ No newline at end of file diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 0b188ae..378196f 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -577,6 +577,10 @@ impl ShipServerState { GameMessage::PlayerSoldItem(player_sold_item) => { handler::message::player_sells_item(id, player_sold_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? }, + GameMessage::FloorItemLimitItemDeletion(floor_item_limit_delete) => { + let block = self.blocks.get_from_client(id, &self.clients).await?; + handler::message::floor_item_limit_deletion(id, floor_item_limit_delete, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await? + }, _ => { let cmsg = msg.clone(); let block = self.blocks.get_from_client(id, &self.clients).await?; -- 2.36.0 From 905bc583c0c3515bef2861c261fa1119bd340b58 Mon Sep 17 00:00:00 2001 From: andy Date: Sun, 12 Feb 2023 02:16:06 +0000 Subject: [PATCH 05/58] clipster --- src/entity/gateway/postgres/models.rs | 4 ++-- src/entity/item/mod.rs | 1 - src/ship/items/actions.rs | 4 +++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/entity/gateway/postgres/models.rs b/src/entity/gateway/postgres/models.rs index 81de203..e1a6c8c 100644 --- a/src/entity/gateway/postgres/models.rs +++ b/src/entity/gateway/postgres/models.rs @@ -664,7 +664,7 @@ impl From for PgItemNoteDetail { }, ItemNote::FloorLimitReached { map_area } => { PgItemNoteDetail::FloorLimitReached { - map_area: map_area, + map_area, } }, } @@ -712,7 +712,7 @@ impl From for ItemNote { bank, }, PgItemNoteDetail::FloorLimitReached { map_area } => ItemNote::FloorLimitReached { - map_area: map_area, + map_area, }, } } diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index 56bf21f..8b1d967 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -10,7 +10,6 @@ pub mod esweapon; use serde::{Serialize, Deserialize}; use crate::entity::character::CharacterEntityId; -use crate::ship::items::ClientItemId; use crate::ship::map::MapArea; use crate::ship::drops::ItemDropType; diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index 8bc3c86..afdd044 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -1161,7 +1161,9 @@ where Box::pin(async move { let transaction = floor_item.with_entity_id(transaction, |mut transaction, entity_id| { async move { - transaction.gateway().add_item_note(&entity_id, ItemNote::FloorLimitReached { map_area: map_area }).await?; + transaction.gateway().add_item_note(&entity_id, ItemNote::FloorLimitReached { + map_area + }).await?; Ok(transaction) }}).await?; Ok(((item_state, transaction), ())) -- 2.36.0 From 81c7e3ee33994d85afac45b554e1beab04c6d6f9 Mon Sep 17 00:00:00 2001 From: andy Date: Sun, 12 Feb 2023 14:32:12 +0000 Subject: [PATCH 06/58] rebase sillyness --- src/ship/items/tasks.rs | 4 ++-- src/ship/packet/handler/message.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ship/items/tasks.rs b/src/ship/items/tasks.rs index 67fd179..2bde925 100644 --- a/src/ship/items/tasks.rs +++ b/src/ship/items/tasks.rs @@ -509,8 +509,8 @@ where }) } -pub async fn floor_item_limit_reached<'a, EG> ( - item_state: &'a mut ItemState, +pub fn floor_item_limit_reached<'a, EG> ( + item_state: &'a ItemState, entity_gateway: &'a mut EG, character: &'a CharacterEntity, item_id: &'a ClientItemId, diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index c219303..f380d14 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -519,9 +519,9 @@ where clients.with(id, |client| { let mut entity_gateway = entity_gateway.clone(); - let mut item_state = item_state.clone(); + let item_state = item_state.clone(); Box::pin(async move { - floor_item_limit_reached(&mut item_state, &mut entity_gateway, &client.character, &ClientItemId(floor_item_limit_delete.item_id), map_area).await + floor_item_limit_reached(&item_state, &mut entity_gateway, &client.character, &ClientItemId(floor_item_limit_delete.item_id), map_area).await })}).await??; Ok(Vec::new()) -} \ No newline at end of file +} -- 2.36.0 From fa7b60dc22fcc72403aed27237a37481f16c32d8 Mon Sep 17 00:00:00 2001 From: jake Date: Tue, 14 Feb 2023 00:59:57 -0700 Subject: [PATCH 07/58] fix dumb itemid problem --- src/ship/packet/handler/room.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 4cdf611..1055b28 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -44,14 +44,15 @@ pub async fn create_room(id: ClientId, }; let area = client_location.get_area(id).await?; - let area_client = client_location.get_local_client(id).await?; + let old_area_client = client_location.get_local_client(id).await?; let lobby_neighbors = client_location.get_client_neighbors(id).await?; let room_id = client_location.create_new_room(id).await?; + let new_area_client = client_location.get_local_client(id).await?; let room = clients.with(id, |client| { let mut item_state = item_state.clone(); Box::pin(async move { - item_state.add_character_to_room(room_id, &client.character, area_client).await; + item_state.add_character_to_room(room_id, &client.character, new_area_client).await; let mut room = RoomState::from_create_room(&create_room, map_builder, drop_table_builder, client.character.section_id, event)?; room.bursting = true; Ok::<_, anyhow::Error>(room) @@ -62,7 +63,7 @@ pub async fn create_room(id: ClientId, let mut result = vec![(id, SendShipPacket::JoinRoom(join_room))]; if let Ok(leader) = client_location.get_area_leader(area).await { - let leave_lobby = SendShipPacket::LeaveLobby(LeaveLobby::new(area_client.local_client.id(), leader.local_client.id())); + let leave_lobby = SendShipPacket::LeaveLobby(LeaveLobby::new(old_area_client.local_client.id(), leader.local_client.id())); result.extend(lobby_neighbors .into_iter() .map(move |c| { -- 2.36.0 From 6fab72fc7a2fbbdb7c0f4638d91c98232c60e472 Mon Sep 17 00:00:00 2001 From: jake Date: Wed, 15 Feb 2023 00:49:49 -0700 Subject: [PATCH 08/58] initial room entities --- src/entity/mod.rs | 1 + src/entity/room.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 src/entity/room.rs diff --git a/src/entity/mod.rs b/src/entity/mod.rs index ba0b6e4..8970e37 100644 --- a/src/entity/mod.rs +++ b/src/entity/mod.rs @@ -2,3 +2,4 @@ pub mod gateway; pub mod account; pub mod character; pub mod item; +pub mod room; diff --git a/src/entity/room.rs b/src/entity/room.rs new file mode 100644 index 0000000..9db194e --- /dev/null +++ b/src/entity/room.rs @@ -0,0 +1,87 @@ +use serde::{Serialize, Deserialize}; + + +use crate::entity::character::{CharacterEntityId, SectionID}; +use crate::ship::room::{Episode, Difficulty, RoomMode}; + + +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)] +pub struct RoomEntityId(pub u32); + + +#[derive(Debug, Copy, Clone)] +pub enum RoomEntityMode { + Single, + Multi, + Challenge, + Battle, +} + + +#[derive(Debug, Clone)] +pub struct RoomEntity { + pub id: RoomEntityId, + pub name: String, + pub section_id: SectionID, + pub mode: RoomEntityMode, + pub episode: Episode, + pub difficulty: Difficulty, +} + + +#[derive(Debug, Clone)] +pub struct NewRoomEntity { + pub name: String, + pub section_id: SectionID, + pub mode: RoomEntityMode, + pub episode: Episode, + pub difficulty: Difficulty, +} + +impl NewRoomEntity { + fn new(name: String, section_id: SectionID, mode: RoomMode) -> NewRoomEntity { + NewRoomEntity { + name: name, + section_id: section_id, + mode: match mode { + RoomMode::Single {..} => RoomEntityMode::Single, + RoomMode::Multi {..} => RoomEntityMode::Multi, + RoomMode::Challenge {..} => RoomEntityMode::Challenge, + RoomMode::Battle {..} => RoomEntityMode::Battle, + }, + episode: match mode { + RoomMode::Single { episode, .. } => episode, + RoomMode::Multi { episode, ..} => episode , + RoomMode::Challenge { episode, ..} => episode, + RoomMode::Battle { episode, ..} => episode, + }, + difficulty: match mode { + RoomMode::Single { difficulty, .. } => difficulty, + RoomMode::Multi { difficulty, ..} => difficulty , + RoomMode::Challenge {..} => Difficulty::Normal, + RoomMode::Battle { difficulty, ..} => difficulty, + }, + } + } +} + + +#[derive(Debug, Copy, Clone)] +pub enum RoomNote { + Create { + character_id: CharacterEntityId, + }, + PlayerJoin { + character_id: CharacterEntityId, + }, + PlayerLeave { + character_id: CharacterEntityId, + }, + QuestStart { + // quest id + }, + QuestComplete { + // quest id + }, + +} -- 2.36.0 From dafd56cd8e6d9bf6f476c6880d73fefc689b70ae Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 18 Feb 2023 00:51:28 -0700 Subject: [PATCH 09/58] minor room refactor, room db table, add room ids to itemnotes --- src/entity/gateway/entitygateway.rs | 10 +- src/entity/gateway/inmemory.rs | 18 +++ .../postgres/migrations/V0012__room.sql | 14 ++ src/entity/gateway/postgres/models.rs | 88 +++++++++-- src/entity/gateway/postgres/postgres.rs | 39 +++++ src/entity/item/mod.rs | 24 ++- src/entity/room.rs | 28 +++- src/ship/items/actions.rs | 115 ++++++++++++--- src/ship/items/tasks.rs | 31 +++- src/ship/packet/handler/direct_message.rs | 14 +- src/ship/packet/handler/quest.rs | 19 +-- src/ship/packet/handler/room.rs | 54 +++++-- src/ship/quests.rs | 75 +++++++--- src/ship/room.rs | 138 ++++++++---------- src/ship/ship.rs | 3 +- 15 files changed, 502 insertions(+), 168 deletions(-) create mode 100644 src/entity/gateway/postgres/migrations/V0012__room.sql diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index 99c65bb..df922ac 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -4,10 +4,10 @@ use futures::future::{Future, BoxFuture}; use crate::entity::account::*; use crate::entity::character::*; use crate::entity::item::*; +use crate::entity::room::*; // TODO: better granularity? -//#[derive(Error, Debug)] #[derive(Error, Debug)] pub enum GatewayError { #[error("unknown error")] @@ -147,6 +147,14 @@ pub trait EntityGateway: Send + Sync { async fn set_character_playtime(&mut self, _char_id: &CharacterEntityId, _playtime: u32) -> Result<(), GatewayError> { unimplemented!(); } + + async fn create_room(&mut self, _room: NewRoomEntity) -> Result { + unimplemented!(); + } + + async fn add_room_note(&mut self, _room_id: RoomEntityId, _note: RoomNote) -> Result<(), GatewayError> { + unimplemented!(); + } } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index 75df8a1..50a650e 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -6,6 +6,7 @@ use crate::entity::account::*; use crate::entity::character::*; use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction, GatewayError}; use crate::entity::item::*; +use crate::entity::room::*; use async_std::sync::{Arc, Mutex}; @@ -766,4 +767,21 @@ impl EntityGateway for InMemoryGateway { Err(GatewayError::Error) } } + + // I do not care to replicate this in testing + async fn create_room(&mut self, room: NewRoomEntity) -> Result { + Ok(RoomEntity { + id: RoomEntityId(0), + name: room.name, + section_id: room.section_id, + episode: room.episode, + difficulty: room.difficulty, + mode: room.mode, + }) + } + + // I do not care to replicate this in testing + async fn add_room_note(&mut self, _room_id: RoomEntityId, _note: RoomNote) -> Result<(), GatewayError> { + Ok(()) + } } diff --git a/src/entity/gateway/postgres/migrations/V0012__room.sql b/src/entity/gateway/postgres/migrations/V0012__room.sql new file mode 100644 index 0000000..750493c --- /dev/null +++ b/src/entity/gateway/postgres/migrations/V0012__room.sql @@ -0,0 +1,14 @@ +create table room { + id serial primary key not null, + name varchar(32) not null, + section_id char not null, + mode char not null, + episode char not null, + difficulty char not null, +}; + +create table room_note ( + room integer references room (id) not null, + note jsonb not null, + created_at timestamptz default current_timestamp not null +); diff --git a/src/entity/gateway/postgres/models.rs b/src/entity/gateway/postgres/models.rs index e1a6c8c..f3a2f39 100644 --- a/src/entity/gateway/postgres/models.rs +++ b/src/entity/gateway/postgres/models.rs @@ -7,7 +7,10 @@ use libpso::util::vec_to_array; use crate::entity::account::*; use crate::entity::character::*; use crate::entity::item::*; +use crate::entity::room::*; use crate::ship::map::MapArea; +use crate::ship::room::{Episode, Difficulty}; +use crate::ship::monster::MonsterType; #[derive(Debug, sqlx::FromRow)] pub struct PgUserAccount { @@ -577,6 +580,16 @@ pub enum PgItemNoteDetail { }, EnemyDrop { character_id: u32, + room_id: u32, + monster_type: MonsterType, + map_area: MapArea, + x: f32, + y: f32, + z: f32, + }, + BoxDrop { + character_id: u32, + room_id: u32, map_area: MapArea, x: f32, y: f32, @@ -592,14 +605,19 @@ pub enum PgItemNoteDetail { y: f32, z: f32, }, - Consumed, + Consumed { + character_id: u32, + }, FedToMag { + character_id: u32, mag: u32, }, BoughtAtShop { character_id: u32, }, - SoldToShop, + SoldToShop { + character_id: u32, + }, Trade { trade_id: u32, character_to: u32, @@ -624,8 +642,16 @@ impl From for PgItemNoteDetail { ItemNote::CharacterCreation{character_id} => PgItemNoteDetail::CharacterCreation { character_id: character_id.0, }, - ItemNote::EnemyDrop{character_id, map_area, x, y, z} => PgItemNoteDetail::EnemyDrop { + ItemNote::EnemyDrop{character_id, room_id, monster_type, map_area, x, y, z} => PgItemNoteDetail::EnemyDrop { + character_id: character_id.0, + room_id: room_id.0, + monster_type, + map_area, + x,y,z, + }, + ItemNote::BoxDrop{character_id, room_id, map_area, x, y, z} => PgItemNoteDetail::BoxDrop { character_id: character_id.0, + room_id: room_id.0, map_area, x,y,z, }, @@ -637,14 +663,19 @@ impl From for PgItemNoteDetail { map_area, x,y,z, }, - ItemNote::Consumed => PgItemNoteDetail::Consumed, - ItemNote::FedToMag{mag} => PgItemNoteDetail::FedToMag{ + ItemNote::Consumed{character_id} => PgItemNoteDetail::Consumed { + character_id: character_id.0, + }, + ItemNote::FedToMag{character_id, mag} => PgItemNoteDetail::FedToMag{ + character_id: character_id.0, mag: mag.0 }, ItemNote::BoughtAtShop{character_id} => PgItemNoteDetail::BoughtAtShop { character_id: character_id.0, }, - ItemNote::SoldToShop => PgItemNoteDetail::SoldToShop, + ItemNote::SoldToShop{character_id} => PgItemNoteDetail::SoldToShop { + character_id: character_id.0, + }, ItemNote::Trade{trade_id, character_to, character_from} => PgItemNoteDetail::Trade { trade_id: trade_id.0, character_to: character_to.0, @@ -677,8 +708,16 @@ impl From for ItemNote { PgItemNoteDetail::CharacterCreation{character_id} => ItemNote::CharacterCreation { character_id: CharacterEntityId(character_id), }, - PgItemNoteDetail::EnemyDrop{character_id, map_area, x, y, z} => ItemNote::EnemyDrop { + PgItemNoteDetail::EnemyDrop{character_id, room_id, monster_type, map_area, x, y, z} => ItemNote::EnemyDrop { character_id: CharacterEntityId(character_id), + room_id: RoomEntityId(room_id), + monster_type, + map_area, + x,y,z, + }, + PgItemNoteDetail::BoxDrop{character_id, room_id, map_area, x, y, z} => ItemNote::BoxDrop { + character_id: CharacterEntityId(character_id), + room_id: RoomEntityId(room_id), map_area, x,y,z, }, @@ -690,14 +729,19 @@ impl From for ItemNote { map_area, x,y,z, }, - PgItemNoteDetail::Consumed => ItemNote::Consumed, - PgItemNoteDetail::FedToMag{mag} => ItemNote::FedToMag{ + PgItemNoteDetail::Consumed{character_id} => ItemNote::Consumed { + character_id: CharacterEntityId(character_id), + }, + PgItemNoteDetail::FedToMag{character_id, mag} => ItemNote::FedToMag{ + character_id: CharacterEntityId(character_id), mag: ItemEntityId(mag) }, PgItemNoteDetail::BoughtAtShop{character_id} => ItemNote::BoughtAtShop { character_id: CharacterEntityId(character_id), }, - PgItemNoteDetail::SoldToShop => ItemNote::SoldToShop, + PgItemNoteDetail::SoldToShop{character_id} => ItemNote::SoldToShop { + character_id: CharacterEntityId(character_id), + }, PgItemNoteDetail::Trade {trade_id, character_to, character_from} => ItemNote::Trade { trade_id: TradeId(trade_id), character_to: CharacterEntityId(character_to), @@ -880,3 +924,27 @@ impl From for TradeEntity { } } } + + +#[derive(Debug, sqlx::FromRow, Serialize)] +pub struct PgRoomEntity { + id: i32, + name: String, + section_id: i8, + mode: i8, + episode: i8, + difficulty: i8, +} + +impl From for RoomEntity { + fn from(other: PgRoomEntity) -> RoomEntity { + RoomEntity { + id: RoomEntityId(other.id as u32), + name: other.name, + section_id: SectionID::from(other.section_id as u8), + mode: RoomEntityMode::from(other.mode as u8), + episode: Episode::try_from(other.episode as u8).unwrap(), + difficulty: Difficulty::try_from(other.difficulty as u8).unwrap(), + } + } +} diff --git a/src/entity/gateway/postgres/postgres.rs b/src/entity/gateway/postgres/postgres.rs index 717f8ca..9bb3be5 100644 --- a/src/entity/gateway/postgres/postgres.rs +++ b/src/entity/gateway/postgres/postgres.rs @@ -10,6 +10,7 @@ use crate::entity::account::*; use crate::entity::character::*; use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction, GatewayError}; use crate::entity::item::*; +use crate::entity::room::*; use super::models::*; use sqlx::postgres::PgPoolOptions; @@ -658,6 +659,28 @@ async fn set_character_playtime(conn: &mut sqlx::PgConnection, char_id: &Charact Ok(()) } +async fn create_room(conn: &mut sqlx::PgConnection, room: NewRoomEntity) -> Result { + sqlx::query_as::<_, PgRoomEntity>("insert into room (name, section_id, mode, episode, difficulty) values ($1, $2, $3, $4, $5) returning *") + .bind(room.name) + .bind(u8::from(room.section_id) as i8) + .bind(u8::from(room.mode) as i8) + .bind(u8::from(room.episode) as i8) + .bind(u8::from(room.difficulty) as i8) + .fetch_one(conn) + .await + .map(|room| room.into()) + .map_err(|err| err.into()) +} + +async fn add_room_note(conn: &mut sqlx::PgConnection, room_id: RoomEntityId, note: RoomNote) -> Result<(), GatewayError> { + sqlx::query("insert into room_note (room, note) values ($1, $2)") + .bind(room_id.0) + .bind(sqlx::types::Json(note)) + .execute(conn) + .await?; + Ok(()) +} + #[async_trait::async_trait] impl EntityGateway for PostgresGateway { type Transaction<'t> = PostgresTransaction<'t> where Self: 't; @@ -797,6 +820,14 @@ impl EntityGateway for PostgresGateway { async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> { set_character_playtime(&mut *self.pool.acquire().await?, char_id, playtime).await } + + async fn create_room(&mut self, room: NewRoomEntity) -> Result { + create_room(&mut *self.pool.acquire().await?, room).await + } + + async fn add_room_note(&mut self, room_id: RoomEntityId, note: RoomNote) -> Result<(), GatewayError> { + add_room_note(&mut *self.pool.acquire().await?, room_id, note).await + } } @@ -923,5 +954,13 @@ impl<'c> EntityGateway for PostgresTransaction<'c> { async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> { set_character_playtime(&mut *self.pgtransaction.lock().await, char_id, playtime).await } + + async fn create_room(&mut self, room: NewRoomEntity) -> Result { + create_room(&mut *self.pgtransaction.lock().await, room).await + } + + async fn add_room_note(&mut self, room_id: RoomEntityId, note: RoomNote) -> Result<(), GatewayError> { + add_room_note(&mut *self.pgtransaction.lock().await, room_id, note).await + } } diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index 8b1d967..7023f7c 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -10,7 +10,9 @@ pub mod esweapon; use serde::{Serialize, Deserialize}; use crate::entity::character::CharacterEntityId; +use crate::entity::room::RoomEntityId; use crate::ship::map::MapArea; +use crate::ship::monster::MonsterType; use crate::ship::drops::ItemDropType; #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)] @@ -35,8 +37,16 @@ pub enum ItemNote { }, EnemyDrop { character_id: CharacterEntityId, - //monster_type: MonsterType, - //droprate: f32, + room_id: RoomEntityId, + monster_type: MonsterType, + map_area: MapArea, + x: f32, + y: f32, + z: f32, + }, + BoxDrop { + character_id: CharacterEntityId, + room_id: RoomEntityId, map_area: MapArea, x: f32, y: f32, @@ -52,15 +62,19 @@ pub enum ItemNote { y: f32, z: f32, }, - Consumed, // TODO: character_id + Consumed { + character_id: CharacterEntityId, + }, FedToMag { - //character_id: CharacterEntityId, + character_id: CharacterEntityId, mag: ItemEntityId, }, BoughtAtShop { character_id: CharacterEntityId, }, - SoldToShop, + SoldToShop { + character_id: CharacterEntityId, + }, Trade { trade_id: TradeId, character_to: CharacterEntityId, diff --git a/src/entity/room.rs b/src/entity/room.rs index 9db194e..d59327e 100644 --- a/src/entity/room.rs +++ b/src/entity/room.rs @@ -11,12 +11,35 @@ pub struct RoomEntityId(pub u32); #[derive(Debug, Copy, Clone)] pub enum RoomEntityMode { - Single, Multi, + Single, Challenge, Battle, } +impl From for RoomEntityMode { + fn from(other: u8) -> RoomEntityMode { + match other { + 0 => RoomEntityMode::Multi, + 1 => RoomEntityMode::Single, + 2 => RoomEntityMode::Challenge, + 3 => RoomEntityMode::Battle, + _ => unreachable!() + } + } +} + +impl From for u8 { + fn from(other: RoomEntityMode) -> u8 { + match other { + RoomEntityMode::Multi => 0, + RoomEntityMode::Single => 1, + RoomEntityMode::Challenge => 2, + RoomEntityMode::Battle => 3, + } + } +} + #[derive(Debug, Clone)] pub struct RoomEntity { @@ -29,6 +52,7 @@ pub struct RoomEntity { } + #[derive(Debug, Clone)] pub struct NewRoomEntity { pub name: String, @@ -66,7 +90,7 @@ impl NewRoomEntity { } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, Serialize)] pub enum RoomNote { Create { character_id: CharacterEntityId, diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index afdd044..ad36f52 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -9,22 +9,23 @@ use std::iter::IntoIterator; use anyhow::Context; use libpso::packet::{ship::Message, messages::GameMessage}; -use crate::ship::map::MapArea; -use crate::ship::ship::SendShipPacket; use crate::entity::character::{CharacterEntity, CharacterEntityId}; use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction}; +use crate::entity::item::{ItemDetail, NewItemEntity, TradeId, ItemModifier}; +use crate::entity::item::tool::Tool; +use crate::entity::room::RoomEntityId; +use crate::ship::map::MapArea; +use crate::ship::ship::SendShipPacket; use crate::ship::items::state::{ItemStateProxy, ItemStateError, AddItemResult, StackedItemDetail, IndividualItemDetail}; use crate::ship::items::bank::{BankItem, BankItemDetail}; use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail}; use crate::ship::items::floor::{FloorItem, FloorItemDetail}; use crate::ship::items::apply_item::{apply_item, ApplyItemAction}; -use crate::entity::item::{ItemDetail, NewItemEntity, TradeId}; -use crate::entity::item::tool::Tool; -use crate::entity::item::ItemModifier; use crate::ship::shops::ShopItem; use crate::ship::drops::{ItemDrop, ItemDropType}; use crate::ship::packet::builder; use crate::ship::location::AreaClient; +use crate::ship::monster::MonsterType; pub enum TriggerCreateItem { Yes, @@ -513,7 +514,9 @@ where Box::pin(async move { let mut transaction = inventory_item.with_entity_id(transaction, |mut transaction, entity_id| { async move { - transaction.gateway().add_item_note(&entity_id, ItemNote::Consumed).await?; + transaction.gateway().add_item_note(&entity_id, ItemNote::Consumed { + character_id: character.id, + }).await?; Ok(transaction) }}).await?; @@ -660,7 +663,9 @@ where let mut transaction = inventory_item.with_entity_id(transaction, |mut transaction, entity_id| { async move { - transaction.gateway().add_item_note(&entity_id, ItemNote::SoldToShop).await?; + transaction.gateway().add_item_note(&entity_id, ItemNote::SoldToShop { + character_id, + }).await?; Ok(transaction) }}).await?; transaction.gateway().set_character_meseta(&character_id, inventory.meseta).await?; @@ -946,13 +951,6 @@ where let entity = transaction.gateway().create_item(NewItemEntity { item: item_detail.clone(), }).await?; - transaction.gateway().add_item_note(&entity.id, ItemNote::EnemyDrop { - character_id, - map_area: item_drop.map_area, - x: item_drop.x, - y: item_drop.y, - z: item_drop.z, - }).await?; FloorItem { item_id, item: FloorItemDetail::Individual(IndividualItemDetail { @@ -969,13 +967,6 @@ where let entity = transaction.gateway().create_item(NewItemEntity { item: ItemDetail::Tool(tool), }).await?; - transaction.gateway().add_item_note(&entity.id, ItemNote::EnemyDrop { - character_id, - map_area: item_drop.map_area, - x: item_drop.x, - y: item_drop.y, - z: item_drop.z, - }).await?; FloorItem { item_id, item: FloorItemDetail::Stacked(StackedItemDetail{ @@ -1005,6 +996,88 @@ where } } + +pub(super) fn item_note_enemy_drop<'a, EG, TR>( + character_id: CharacterEntityId, + room_id: RoomEntityId, + monster_type: MonsterType, +) -> impl Fn((ItemStateProxy, TR), FloorItem) + -> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + Clone +where + EG: EntityGateway, + TR: EntityGatewayTransaction + 'a, +{ + move |(item_state, mut transaction), floor_item| { + Box::pin(async move { + match &floor_item.item { + FloorItemDetail::Individual(individual) => { + transaction.gateway().add_item_note(&individual.entity_id, ItemNote::EnemyDrop { + character_id, + room_id, + monster_type, + map_area: floor_item.map_area, + x: floor_item.x, + y: floor_item.y, + z: floor_item.z, + }).await?; + }, + FloorItemDetail::Stacked(stacked) => { + transaction.gateway().add_item_note(&stacked.entity_ids[0], ItemNote::EnemyDrop { + character_id, + room_id, + monster_type, + map_area: floor_item.map_area, + x: floor_item.x, + y: floor_item.y, + z: floor_item.z, + }).await?; + }, + _ => {}, + } + Ok(((item_state, transaction), floor_item)) + }) + } +} + +pub(super) fn item_note_box_drop<'a, EG, TR>( + character_id: CharacterEntityId, + room_id: RoomEntityId, +) -> impl Fn((ItemStateProxy, TR), FloorItem) + -> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + Clone +where + EG: EntityGateway, + TR: EntityGatewayTransaction + 'a, +{ + move |(item_state, mut transaction), floor_item| { + Box::pin(async move { + match &floor_item.item { + FloorItemDetail::Individual(individual) => { + transaction.gateway().add_item_note(&individual.entity_id, ItemNote::BoxDrop { + character_id, + room_id, + map_area: floor_item.map_area, + x: floor_item.x, + y: floor_item.y, + z: floor_item.z, + }).await?; + }, + FloorItemDetail::Stacked(stacked) => { + transaction.gateway().add_item_note(&stacked.entity_ids[0], ItemNote::BoxDrop { + character_id, + room_id, + map_area: floor_item.map_area, + x: floor_item.x, + y: floor_item.y, + z: floor_item.z, + }).await?; + }, + _ => {}, + } + Ok(((item_state, transaction), floor_item)) + }) + } +} + pub(super) fn add_item_to_local_floor<'a, EG, TR>( character_id: CharacterEntityId, ) -> impl Fn((ItemStateProxy, TR), FloorItem) diff --git a/src/ship/items/tasks.rs b/src/ship/items/tasks.rs index 2bde925..d8603f0 100644 --- a/src/ship/items/tasks.rs +++ b/src/ship/items/tasks.rs @@ -6,15 +6,17 @@ use crate::ship::ship::SendShipPacket; use crate::ship::map::MapArea; use crate::entity::character::{CharacterEntity, CharacterEntityId}; use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction}; +use crate::entity::item::ItemModifier; +use crate::entity::room::RoomEntityId; use crate::ship::items::state::{ItemState, ItemStateProxy, IndividualItemDetail}; use crate::ship::items::itemstateaction::{ItemStateAction, ItemAction}; use crate::ship::items::inventory::InventoryItem; use crate::ship::items::floor::FloorItem; -use crate::entity::item::ItemModifier; use crate::ship::shops::ShopItem; use crate::ship::trade::TradeItem; use crate::ship::location::AreaClient; use crate::ship::drops::ItemDrop; +use crate::ship::monster::MonsterType; use crate::ship::items::actions; @@ -465,6 +467,32 @@ pub fn enemy_drops_item<'a, EG> ( item_state: &'a mut ItemState, entity_gateway: &'a mut EG, character_id: CharacterEntityId, + room_id: RoomEntityId, + monster_type: MonsterType, + item_drop: ItemDrop) + -> BoxFuture<'a, Result> +where + EG: EntityGateway + 'static, +{ + entity_gateway.with_transaction(move |transaction| async move { + let item_state_proxy = ItemStateProxy::new(item_state.clone()); + let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default() + .act(actions::convert_item_drop_to_floor_item(character_id, item_drop)) + .act(actions::item_note_enemy_drop(character_id, room_id, monster_type)) + .act(actions::add_item_to_local_floor(character_id)) + .commit((item_state_proxy, transaction)) + .await?; + + item_state_proxy.commit().await; + Ok((transaction, floor_item)) + }) +} + +pub fn box_drops_item<'a, EG> ( + item_state: &'a mut ItemState, + entity_gateway: &'a mut EG, + character_id: CharacterEntityId, + room_id: RoomEntityId, item_drop: ItemDrop) -> BoxFuture<'a, Result> where @@ -474,6 +502,7 @@ where let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default() .act(actions::convert_item_drop_to_floor_item(character_id, item_drop)) + .act(actions::item_note_box_drop(character_id, room_id)) .act(actions::add_item_to_local_floor(character_id)) .commit((item_state_proxy, transaction)) .await?; diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index 81f0146..3c914e8 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/src/ship/packet/handler/direct_message.rs @@ -18,7 +18,7 @@ use crate::ship::shops::{ShopItem, ToolShopItem, ArmorShopItem}; use crate::ship::items::state::{ItemState, ItemStateError}; use crate::ship::items::floor::{FloorType, FloorItemDetail}; use crate::ship::items::actions::TriggerCreateItem; -use crate::ship::items::tasks::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, enemy_drops_item, take_meseta, apply_modifier}; +use crate::ship::items::tasks::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, enemy_drops_item, box_drops_item, take_meseta, apply_modifier}; const BANK_ACTION_DEPOSIT: u8 = 0; const BANK_ACTION_WITHDRAW: u8 = 1; @@ -89,8 +89,8 @@ where EG: EntityGateway + 'static, { let room_id = client_location.get_room(id).await?; - let monster = rooms.with(room_id, |room| Box::pin(async move { - room.maps.enemy_by_id(request_item.enemy_id as usize) + let (room_entity_id, monster) = rooms.with(room_id, |room| Box::pin(async move { + Ok::<_, anyhow::Error>((room.room_id, room.maps.enemy_by_id(request_item.enemy_id as usize)?)) })).await??; if monster.dropped_item { @@ -121,7 +121,7 @@ where client.character.id })).await?; - let floor_item = enemy_drops_item(item_state, entity_gateway, character_id, item_drop).await?; + let floor_item = enemy_drops_item(item_state, entity_gateway, character_id, room_entity_id, monster.monster, item_drop).await?; let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, &floor_item)?; item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))); @@ -200,8 +200,8 @@ where EG: EntityGateway + Clone + 'static { let room_id = client_location.get_room(id).await?; - let box_object = rooms.with(room_id, |room| Box::pin(async move { - room.maps.object_by_id(box_drop_request.object_id as usize) + let (room_entity_id, box_object) = rooms.with(room_id, |room| Box::pin(async move { + Ok::<_, anyhow::Error>((room.room_id, room.maps.object_by_id(box_drop_request.object_id as usize)?)) })).await??; if box_object.dropped_item { @@ -232,7 +232,7 @@ where let character_id = clients.with(area_client.client, |client| Box::pin(async move { client.character.id })).await?; - let floor_item = enemy_drops_item(item_state, entity_gateway, character_id, item_drop).await?; + let floor_item = box_drops_item(item_state, entity_gateway, character_id, room_entity_id, item_drop).await?; //let floor_item = enemy_drops_item(item_state, &mut entity_gateway, client.character.id, item_drop).await?; let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, &floor_item)?; item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))) diff --git a/src/ship/packet/handler/quest.rs b/src/ship/packet/handler/quest.rs index e451f9f..3dee2ff 100644 --- a/src/ship/packet/handler/quest.rs +++ b/src/ship/packet/handler/quest.rs @@ -3,7 +3,7 @@ use futures::stream::{FuturesOrdered, StreamExt}; use libpso::packet::ship::*; use crate::common::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, ShipError, Clients, ShipEvent}; -use crate::ship::room::Rooms; +use crate::ship::room::{Rooms, QuestCategoryType}; use crate::ship::map::enemy::RareMonsterAppearTable; use crate::ship::location::{ClientLocation}; use crate::ship::packet::builder::quest; @@ -46,8 +46,9 @@ pub async fn send_quest_category_list(id: ClientId, let room_id = client_location.get_room(id).await?; let rql = rql.clone(); rooms.with_mut(room_id, |room| Box::pin(async move { - let qcl = quest::quest_category_list(&room.quests[rql.flag.clamp(0, (room.quests.len() - 1) as u32) as usize]); - room.set_quest_group(rql.flag as usize); + //let qcl = quest::quest_category_list(&room.quests[rql.flag.clamp(0, (room.quests.len() - 1) as u32) as usize]); + room.quest_group = rql.flag.into(); + let qcl = quest::quest_category_list(room.quests()); Ok(vec![(id, SendShipPacket::QuestCategoryList(qcl))]) })).await? } @@ -59,10 +60,10 @@ pub async fn select_quest_category(id: ClientId, -> Result, anyhow::Error> { let room_id = client_location.get_room(id).await?; rooms.with(room_id, |room| Box::pin(async move { - let (_, category_quests) = room.quests[room.quest_group.value()].iter() + let (_, category_quests) = room.quests() + .iter() .nth(menuselect.item as usize) .ok_or_else(|| ShipError::InvalidQuestCategory(menuselect.item as u16))?; - let ql = quest::quest_list(menuselect.item, category_quests); Ok(vec![(id, SendShipPacket::QuestOptionList(ql))]) })).await? @@ -76,7 +77,7 @@ pub async fn quest_detail(id: ClientId, -> Result, anyhow::Error> { let room_id = client_location.get_room(id).await?; rooms.with(room_id, |room| Box::pin(async move { - let (_, category_quests) = room.quests[room.quest_group.value()].iter() + let (_, category_quests) = room.quests().iter() .nth(questdetailrequest.category as usize) .ok_or_else(|| ShipError::InvalidQuestCategory(questdetailrequest.category))?; @@ -105,7 +106,7 @@ pub async fn player_chose_quest(id: ClientId, rooms.with_mut(room_id, |room| { let clients = clients.clone(); Box::pin(async move { - let quest = room.quests[room.quest_group.value()].iter() + let quest = room.quests().iter() .nth(questmenuselect.category as usize) .ok_or_else(|| ShipError::InvalidQuestCategory(questmenuselect.category))? .1 @@ -149,7 +150,7 @@ pub async fn quest_file_request(id: ClientId, let quest_file_request = quest_file_request.clone(); rooms.with(room_id, |room| Box::pin(async move { let (category_id, quest_id, datatype) = parse_filename(&quest_file_request.filename)?; - let (_, category_quests) = room.quests[room.quest_group.value()].iter() + let (_, category_quests) = room.quests().iter() .nth(category_id as usize) .ok_or_else(|| ShipError::InvalidQuestCategory(category_id))?; @@ -182,7 +183,7 @@ pub async fn quest_chunk_ack(id: ClientId, let quest_chunk_ack = quest_chunk_ack.clone(); rooms.with(room_id, |room| Box::pin(async move { let (category_id, quest_id, datatype) = parse_filename(&quest_chunk_ack.filename)?; - let (_, category_quests) = room.quests[room.quest_group.value()].iter() + let (_, category_quests) = room.quests().iter() .nth(category_id as usize) .ok_or_else(|| ShipError::InvalidQuestCategory(category_id))?; diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 1055b28..ca9ea5b 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -7,7 +7,9 @@ use libpso::packet::ship::*; use libpso::packet::messages::*; use crate::common::serverstate::ClientId; use crate::common::leveltable::LEVEL_TABLE; +use crate::entity::gateway::EntityGateway; use crate::entity::character::SectionID; +use crate::entity::room::{RoomEntity, RoomEntityId, NewRoomEntity, RoomEntityMode}; use crate::ship::drops::DropTable; use crate::ship::ship::{SendShipPacket, Clients, ShipEvent}; use crate::ship::room::{Rooms, Episode, Difficulty, RoomState, RoomMode}; @@ -17,20 +19,25 @@ use crate::ship::packet::builder; use crate::ship::items::state::ItemState; #[allow(clippy::too_many_arguments)] -pub async fn create_room(id: ClientId, - create_room: CreateRoom, - client_location: &mut ClientLocation, - clients: &Clients, - item_state: &mut ItemState, - rooms: &Rooms, - map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, - event: ShipEvent) - -> Result, anyhow::Error> { +pub async fn create_room(id: ClientId, + create_room: CreateRoom, + entity_gateway: &mut EG, + client_location: &mut ClientLocation, + clients: &Clients, + item_state: &mut ItemState, + rooms: &Rooms, + map_builder: Arc Maps + Send + Sync>>, + drop_table_builder: Arc DropTable + Send + Sync>>, + event: ShipEvent) + -> Result, anyhow::Error> +where + EG: EntityGateway + Clone + 'static, +{ let level = clients.with(id, |client| Box::pin(async move { LEVEL_TABLE.get_level_from_exp(client.character.char_class, client.character.exp) })).await?; - match Difficulty::try_from(create_room.difficulty)? { + let difficulty = Difficulty::try_from(create_room.difficulty)?; + match difficulty { Difficulty::Ultimate if level < 80 => { return Ok(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto create Ultimate rooms.".into())))]) }, @@ -49,11 +56,34 @@ pub async fn create_room(id: ClientId, let room_id = client_location.create_new_room(id).await?; let new_area_client = client_location.get_local_client(id).await?; + + + let name = String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).to_string(); + let mode = match (create_room.battle, create_room.challenge, create_room.single_player) { + (1, 0, 0) => RoomEntityMode::Battle, + (0, 1, 0) => RoomEntityMode::Challenge, + (0, 0, 1) => RoomEntityMode::Single, + _ => RoomEntityMode::Multi, + }; + let episode = create_room.episode.try_into()?; + let difficulty = create_room.difficulty.try_into()?; + let room = clients.with(id, |client| { let mut item_state = item_state.clone(); + let mut entity_gateway = entity_gateway.clone(); Box::pin(async move { item_state.add_character_to_room(room_id, &client.character, new_area_client).await; - let mut room = RoomState::from_create_room(&create_room, map_builder, drop_table_builder, client.character.section_id, event)?; + let room_entity = entity_gateway.create_room(NewRoomEntity { + name: name.clone(), + section_id: client.character.section_id, + mode, + episode, + difficulty, + }).await?; + + let mut room = RoomState::new(room_entity.id, mode, episode, difficulty, + client.character.section_id, name, create_room.password, event, + map_builder, drop_table_builder)?; room.bursting = true; Ok::<_, anyhow::Error>(room) })}).await??; diff --git a/src/ship/quests.rs b/src/ship/quests.rs index 02c1906..e0b8c8c 100644 --- a/src/ship/quests.rs +++ b/src/ship/quests.rs @@ -11,7 +11,7 @@ use ages_prs::{LegacyPrsDecoder, LegacyPrsEncoder}; use byteorder::{LittleEndian, ReadBytesExt}; use libpso::util::array_to_utf16; use crate::ship::map::{MapArea, MapAreaError, MapObject, MapEnemy, enemy_data_from_stream, objects_from_stream}; -use crate::ship::room::Episode; +use crate::ship::room::{Episode, RoomMode}; use crate::ship::map::area::{MapAreaLookup, MapAreaLookupBuilder}; @@ -152,11 +152,14 @@ fn parse_dat(dat: &[u8], episode: &Episode, map_areas: &MapAreaLookup) -> Result } #[derive(Error, Debug)] -#[error("")] pub enum QuestLoadError { + #[error("io error {0}")] IoError(#[from] std::io::Error), + #[error("parse dat error {0}")] ParseDatError(#[from] ParseDatError), + #[error("could not read metadata")] CouldNotReadMetadata, + #[error("could not load config file")] CouldNotLoadConfigFile, } @@ -233,7 +236,7 @@ pub fn load_quest(bin_path: PathBuf, dat_path: PathBuf, quest_path: PathBuf) -> } -pub fn load_quests(mut quest_path: PathBuf) -> Result { +pub fn load_quests_path(mut quest_path: PathBuf) -> Result { let mut f = File::open(quest_path.clone()).map_err(|_| QuestLoadError::CouldNotLoadConfigFile)?; let mut s = String::new(); f.read_to_string(&mut s)?; @@ -242,28 +245,58 @@ pub fn load_quests(mut quest_path: PathBuf) -> Result let ql: BTreeMap = toml::from_str(s.as_str()).map_err(|_| QuestLoadError::CouldNotLoadConfigFile)?; Ok(ql.into_iter().map(|(category, category_details)| { - let quests = category_details.quests - .into_iter() - .filter_map(|quest| { - load_quest(quest.bin.into(), quest.dat.into(), quest_path.to_path_buf()) - .and_then(|quest | { - if used_quest_ids.contains(&quest.id) { - warn!("quest id already exists: {}", quest.id); - return None; - } - used_quest_ids.insert(quest.id); - Some(quest) - }) - }); - (QuestCategory{ - index: category_details.list_order, - name: category, - description: category_details.description, - }, quests.collect()) + ( + QuestCategory { + index: category_details.list_order, + name: category, + description: category_details.description, + }, + category_details.quests + .into_iter() + .filter_map(|quest| { + load_quest(quest.bin.into(), quest.dat.into(), quest_path.to_path_buf()) + .and_then(|quest | { + if used_quest_ids.contains(&quest.id) { + warn!("quest id already exists: {}", quest.id); + return None; + } + used_quest_ids.insert(quest.id); + Some(quest) + }) + }) + .collect() + ) }).collect()) } +pub fn load_standard_quests(mode: RoomMode) -> Result { + match mode { + RoomMode::Single {episode, difficulty } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "single", "quests.toml"])) + }, + RoomMode::Multi {episode, difficulty } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "multi", "quests.toml"])) + }, + _ => { + Ok(BTreeMap::new()) + } + } +} + +pub fn load_government_quests(mode: RoomMode) -> Result { + match mode { + RoomMode::Single {episode, difficulty } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "government", "quests.toml"])) + }, + RoomMode::Multi {episode, difficulty } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "government", "quests.toml"])) + }, + _ => { + Ok(BTreeMap::new()) + } + } +} diff --git a/src/ship/room.rs b/src/ship/room.rs index 87e5585..69820b1 100644 --- a/src/ship/room.rs +++ b/src/ship/room.rs @@ -11,6 +11,7 @@ use rand::Rng; use crate::ship::map::Maps; use crate::ship::drops::DropTable; use crate::entity::character::SectionID; +use crate::entity::room::{RoomEntityId, RoomEntityMode}; use crate::ship::monster::{load_monster_stats_table, MonsterType, MonsterStats}; use crate::ship::map::area::MapAreaLookup; use crate::ship::quests; @@ -55,7 +56,7 @@ impl Rooms { None => false, } } - + pub async fn with<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result where T: Send, @@ -92,7 +93,7 @@ impl Rooms { Err(ShipError::InvalidRoom(room_id.0 as u32).into()) } } - + pub async fn get(&self, room_id: RoomId) -> RwLockReadGuard> { self.0 .get(room_id.0) @@ -282,8 +283,15 @@ impl From for QuestCategoryType { fn from(f: usize) -> QuestCategoryType { match f { 0 => QuestCategoryType::Standard, - 1 => QuestCategoryType::Government, - _ => QuestCategoryType::Standard, // TODO: panic? + _ => QuestCategoryType::Government, + } + } +} +impl From for QuestCategoryType { + fn from(f: u32) -> QuestCategoryType { + match f { + 0 => QuestCategoryType::Standard, + _ => QuestCategoryType::Government, } } } @@ -298,6 +306,7 @@ impl QuestCategoryType { } pub struct RoomState { + pub room_id: RoomEntityId, pub mode: RoomMode, pub name: String, pub password: [u16; 16], @@ -309,22 +318,22 @@ pub struct RoomState { pub monster_stats: Box>, pub map_areas: MapAreaLookup, pub quest_group: QuestCategoryType, - pub quests: Vec, - // items on ground + pub standard_quests: quests::QuestList, + pub government_quests: quests::QuestList, // enemy info } impl RoomState { pub fn get_flags_for_room_list(&self) -> u8 { let mut flags = 0u8; - + match self.mode { RoomMode::Single {..} => {flags += 0x04} RoomMode::Battle {..} => {flags += 0x10}, RoomMode::Challenge {..} => {flags += 0x20}, _ => {flags += 0x40}, }; - + if self.password[0] > 0 { flags += 0x02; } @@ -345,85 +354,58 @@ impl RoomState { difficulty + 0x22 } - pub fn set_quest_group(&mut self, group: usize) { - self.quest_group = QuestCategoryType::from(group); - } - - pub fn from_create_room(create_room: &libpso::packet::ship::CreateRoom, - map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, - section_id: SectionID, - event: ShipEvent) - -> Result { - if [create_room.battle, create_room.challenge, create_room.single_player].iter().sum::() > 1 { - return Err(RoomCreationError::InvalidMode) - } - - let room_mode = if create_room.battle == 1 { - RoomMode::Battle { - episode: create_room.episode.try_into()?, - difficulty: create_room.difficulty.try_into()?, - } - } - else if create_room.challenge == 1 { - RoomMode::Challenge { - episode: create_room.episode.try_into()?, - } - } - else if create_room.single_player == 1 { - RoomMode::Single { - episode: create_room.episode.try_into()?, - difficulty: create_room.difficulty.try_into()?, - } + pub fn quests(&self) -> &quests::QuestList { + match self.quest_group { + QuestCategoryType::Standard => &self.standard_quests, + QuestCategoryType::Government => &self.government_quests, } - else { // normal multimode - RoomMode::Multi { - episode: create_room.episode.try_into()?, - difficulty: create_room.difficulty.try_into()?, - } - }; - + } - // push the usual set of quests for the selected mode - let mut qpath = PathBuf::from("data/quests/bb"); - qpath.push(room_mode.episode().to_string()); - qpath.push(room_mode.to_string()); - qpath.push("quests.toml"); - let mut room_quests = Vec::new(); - let quest_list = match quests::load_quests(qpath) { - Ok(qlist) => qlist, - Err(_) => return Err(RoomCreationError::CouldNotLoadQuests), + pub fn new (room_id: RoomEntityId, + mode: RoomEntityMode, + episode: Episode, + difficulty: Difficulty, + section_id: SectionID, + name: String, + password: [u16; 16], + event: ShipEvent, + map_builder: Arc Maps + Send + Sync>>, + drop_table_builder: Arc DropTable + Send + Sync>>, + ) -> Result { + let mode = match mode { + RoomEntityMode::Single => RoomMode::Single { + episode, + difficulty, + }, + RoomEntityMode::Multi => RoomMode::Multi { + episode, + difficulty, + }, + RoomEntityMode::Challenge => RoomMode::Challenge { + episode, + }, + RoomEntityMode::Battle => RoomMode::Battle { + episode, + difficulty, + }, }; - room_quests.push(quest_list); - - // if multiplayer also push the government quests - if let RoomMode::Multi {..} = room_mode { - qpath = PathBuf::from("data/quests/bb/"); - qpath.push(room_mode.episode().to_string()); - qpath.push("government/quests.toml"); - - let quest_list = match quests::load_quests(qpath) { - Ok(qlist) => qlist, - Err(_) => return Err(RoomCreationError::CouldNotLoadQuests), - }; - - room_quests.push(quest_list); - } - Ok(RoomState { - monster_stats: Box::new(load_monster_stats_table(&room_mode).map_err(|_| RoomCreationError::CouldNotLoadMonsterStats(room_mode))?), - mode: room_mode, + room_id, + monster_stats: Box::new(load_monster_stats_table(&mode).map_err(|_| RoomCreationError::CouldNotLoadMonsterStats(mode))?), + mode, random_seed: rand::thread_rng().gen(), - name: String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).into(), - password: create_room.password, - maps: map_builder(room_mode, event), + name, + password, + maps: map_builder(mode, event), section_id, - drop_table: Box::new(drop_table_builder(room_mode.episode(), room_mode.difficulty(), section_id)), + drop_table: Box::new(drop_table_builder(episode, difficulty, section_id)), bursting: false, - map_areas: MapAreaLookup::new(&room_mode.episode()), + map_areas: MapAreaLookup::new(&episode), quest_group: QuestCategoryType::Standard, - quests: room_quests, + standard_quests: quests::load_standard_quests(mode)?, + government_quests: quests::load_government_quests(mode)?, }) + } } diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 378196f..e4d94c8 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -757,7 +757,8 @@ impl ServerState for ShipServerState { }, RecvShipPacket::CreateRoom(create_room) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::room::create_room(id, create_room, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.map_builder.clone(), self.drop_table_builder.clone(), self.event).await? + handler::room::create_room(id, create_room, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, + &block.rooms, self.map_builder.clone(), self.drop_table_builder.clone(), self.event).await? }, RecvShipPacket::RoomNameRequest(_req) => { let block = self.blocks.get_from_client(id, &self.clients).await?; -- 2.36.0 From 2654496f8c429bc084081dcf11fcc14e99933d71 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 18 Feb 2023 15:07:31 -0700 Subject: [PATCH 10/58] update to sqlx 6.2 --- Cargo.toml | 2 +- src/entity/gateway/postgres/postgres.rs | 68 ++++++++++++------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d62e110..c2e511d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ async-recursion= "1.0.0" lazy_static = "1.4.0" barrel = { version = "0.6.5", features = ["pg"] } refinery = { version = "0.5.0", features = ["postgres"] } -sqlx = { version = "0.5.10", features = ["runtime-async-std-native-tls", "postgres", "json", "chrono"] } +sqlx = { version = "0.6.2", features = ["runtime-async-std-native-tls", "postgres", "json", "chrono"] } strum = "0.19.5" strum_macros = "0.19" anyhow = { version = "1.0.68", features = ["backtrace"] } diff --git a/src/entity/gateway/postgres/postgres.rs b/src/entity/gateway/postgres/postgres.rs index 9bb3be5..c31217f 100644 --- a/src/entity/gateway/postgres/postgres.rs +++ b/src/entity/gateway/postgres/postgres.rs @@ -179,7 +179,7 @@ async fn create_user(conn: &mut sqlx::PgConnection, user: NewUserAccountEntity) async fn get_user_by_id(conn: &mut sqlx::PgConnection, id: UserAccountId) -> Result { let user = sqlx::query_as::<_, PgUserAccount>("select * from user_accounts where id = $1") - .bind(id.0) + .bind(id.0 as i32) .fetch_one(conn).await?; Ok(user.into()) } @@ -200,8 +200,8 @@ async fn save_user(conn: &mut sqlx::PgConnection, user: &UserAccountEntity) -> R .bind(&user.password) .bind(user.banned_until) .bind(user.muted_until) - .bind(user.flags) - .bind(user.id.0) + .bind(user.flags as i32) + .bind(user.id.0 as i32) .execute(conn).await?; Ok(()) } @@ -210,7 +210,7 @@ async fn create_user_settings(conn: &mut sqlx::PgConnection, settings: NewUserSe { let new_settings = sqlx::query_as::<_, PgUserSettings>("insert into user_settings (user_account, blocked_users, key_config, joystick_config, option_flags, shortcuts, symbol_chats, team_name) values ($1, $2, $3, $4, $5, $6, $7, $8) returning *;") - .bind(settings.user_id.0) + .bind(settings.user_id.0 as i32) .bind(settings.settings.blocked_users.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::>()) .bind(settings.settings.keyboard_config.to_vec()) .bind(settings.settings.gamepad_config.to_vec()) @@ -225,7 +225,7 @@ async fn create_user_settings(conn: &mut sqlx::PgConnection, settings: NewUserSe async fn get_user_settings_by_user(conn: &mut sqlx::PgConnection, user: &UserAccountEntity) -> Result { let settings = sqlx::query_as::<_, PgUserSettings>("select * from user_settings where user_account = $1") - .bind(user.id.0) + .bind(user.id.0 as i32) .fetch_one(conn).await?; Ok(settings.into()) } @@ -236,11 +236,11 @@ async fn save_user_settings(conn: &mut sqlx::PgConnection, settings: &UserSettin .bind(settings.settings.blocked_users.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::>()) .bind(&settings.settings.keyboard_config.to_vec()) .bind(&settings.settings.gamepad_config.to_vec()) - .bind(settings.settings.option_flags) + .bind(settings.settings.option_flags as i32) .bind(&settings.settings.shortcuts.to_vec()) .bind(&settings.settings.symbol_chats.to_vec()) .bind(settings.settings.team_name.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::>()) - .bind(settings.id.0) + .bind(settings.id.0 as i32) .execute(conn).await?; Ok(()) } @@ -263,7 +263,7 @@ async fn create_character(conn: &mut sqlx::PgConnection, char: NewCharacterEntit $26, $27, $28, $29, $30) returning *;"#; let character = sqlx::query_as::<_, PgCharacter>(q) - .bind(char.user_id.0) + .bind(char.user_id.0 as i32) .bind(char.slot as i16) .bind(char.name) .bind(char.exp as i32) @@ -301,7 +301,7 @@ async fn create_character(conn: &mut sqlx::PgConnection, char: NewCharacterEntit async fn get_characters_by_user(conn: &mut sqlx::PgConnection, user: &UserAccountEntity) -> Result<[Option; 4], GatewayError> { let stream = sqlx::query_as::<_, PgCharacter>("select * from player_character where user_account = $1 and slot < 4 order by created_at;") - .bind(user.id.0) + .bind(user.id.0 as i32) .fetch(conn); Ok(stream.fold(core::array::from_fn(|_| None), |mut acc, char| async move { @@ -321,7 +321,7 @@ async fn save_character(conn: &mut sqlx::PgConnection, char: &CharacterEntity) - evade=$24, luck=$25, hp=$26, tp=$27, tech_menu=$28, option_flags=$29, playtime=$30 where id=$31;"#; sqlx::query(q) - .bind(char.user_id.0) // $1 + .bind(char.user_id.0 as i32) // $1 .bind(char.slot as i16) // $2 .bind(&char.name) // $3 .bind(char.exp as i32) // $4 @@ -371,7 +371,7 @@ async fn create_item(conn: &mut sqlx::PgConnection, item: NewItemEntity) -> Resu async fn add_item_note(conn: &mut sqlx::PgConnection, item_id: &ItemEntityId, item_note: ItemNote) -> Result<(), GatewayError> { sqlx::query("insert into item_note(item, note) values ($1, $2)") - .bind(item_id.0) + .bind(item_id.0 as i32) .bind(sqlx::types::Json(PgItemNoteDetail::from(item_note))) .execute(conn).await?; Ok(()) @@ -380,7 +380,7 @@ async fn add_item_note(conn: &mut sqlx::PgConnection, item_id: &ItemEntityId, it async fn feed_mag(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntityId, tool_item_id: &ItemEntityId) -> Result<(), GatewayError> { sqlx::query("insert into mag_modifier (mag, modifier) values ($1, $2);") - .bind(mag_item_id.0) + .bind(mag_item_id.0 as i32) .bind(sqlx::types::Json(PgMagModifierDetail::from(mag::MagModifier::FeedMag{food: *tool_item_id}))) .execute(conn).await?; Ok(()) @@ -389,7 +389,7 @@ async fn feed_mag(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntityId, too async fn change_mag_owner(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntityId, character: &CharacterEntity) -> Result<(), GatewayError> { sqlx::query("insert into mag_modifier (mag, modifier) values ($1, $2);") - .bind(mag_item_id.0) + .bind(mag_item_id.0 as i32) .bind(sqlx::types::Json(PgMagModifierDetail::from(mag::MagModifier::OwnerChange(character.char_class, character.section_id)))) .execute(conn).await?; Ok(()) @@ -398,7 +398,7 @@ async fn change_mag_owner(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntit async fn use_mag_cell(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntityId, mag_cell_id: &ItemEntityId) -> Result<(), GatewayError> { sqlx::query("insert into mag_modifier (mag, modifier) values ($1, $2);") - .bind(mag_item_id.0) + .bind(mag_item_id.0 as i32) .bind(sqlx::types::Json(PgMagModifierDetail::from(mag::MagModifier::MagCell(*mag_cell_id)))) .execute(conn).await?; Ok(()) @@ -407,7 +407,7 @@ async fn use_mag_cell(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntityId, async fn add_weapon_modifier(conn: &mut sqlx::PgConnection, item_id: &ItemEntityId, modifier: &weapon::WeaponModifier) -> Result<(), GatewayError> { sqlx::query("insert into weapon_modifier (weapon, modifier) values ($1, $2);") - .bind(item_id.0) + .bind(item_id.0 as i32) .bind(sqlx::types::Json(modifier)) .execute(conn).await?; Ok(()) @@ -417,7 +417,7 @@ async fn get_character_inventory(conn: &mut sqlx::PgConnection, char_id: &Charac { let conn = Arc::new(Mutex::new(conn.begin().await?)); // this is some degen shit let inventory = sqlx::query_as::<_, PgInventoryEntity>("select * from inventory where pchar = $1") - .bind(char_id.0) + .bind(char_id.0 as i32) .fetch_one(&mut **conn.lock().await).await?; Ok(InventoryEntity::new( @@ -442,14 +442,14 @@ async fn get_character_bank(conn: &mut sqlx::PgConnection, char_id: &CharacterEn let bank = match bank_identifier { BankIdentifier::Character => { sqlx::query_as::<_, PgInventoryEntity>("select * from bank where pchar = $1") - .bind(char_id.0) + .bind(char_id.0 as i32) .fetch_one(&mut **conn.lock().await).await? }, BankIdentifier::Shared(bank_name) => { sqlx::query_as::<_, PgInventoryEntity>("select player_character.id as pchar, shared_bank.items as items from shared_bank join player_character on shared_bank.user_account = player_character.user_account where player_character.id = $1 and shared_bank.name = $2") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(&bank_name.0) .fetch_optional(&mut **conn.lock().await) .await? @@ -492,7 +492,7 @@ async fn set_character_inventory(conn: &mut sqlx::PgConnection, char_id: &Charac .collect::>(); sqlx::query("insert into inventory (pchar, items) values ($1, $2) on conflict (pchar) do update set items = $2") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(sqlx::types::Json(inventory)) .execute(conn) .await?; @@ -517,7 +517,7 @@ async fn set_character_bank(conn: &mut sqlx::PgConnection, char_id: &CharacterEn match bank_identifier { BankIdentifier::Character => { sqlx::query("insert into bank (pchar, items, name) values ($1, $2, '') on conflict (pchar, name) do update set items = $2") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(sqlx::types::Json(bank)) .execute(conn) .await?; @@ -527,7 +527,7 @@ async fn set_character_bank(conn: &mut sqlx::PgConnection, char_id: &CharacterEn select player_character.user_account, $2, $3 from player_character where player_character.id = $1 on conflict (user_account, name) do update set items = $2;") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(sqlx::types::Json(bank)) .bind(&bank_name.0) .execute(conn) @@ -540,7 +540,7 @@ async fn set_character_bank(conn: &mut sqlx::PgConnection, char_id: &CharacterEn async fn get_character_equips(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId) -> Result { let equips = sqlx::query_as::<_, PgEquipped>("select * from equipped where pchar = $1") - .bind(char_id.0) + .bind(char_id.0 as i32) .fetch_one(conn) .await?; @@ -551,7 +551,7 @@ async fn set_character_equips(conn: &mut sqlx::PgConnection, char_id: &Character { sqlx::query(r#"insert into equipped (pchar, weapon, armor, shield, unit0, unit1, unit2, unit3, mag) values ($1, $2, $3, $4, $5, $6, $7, $8, $9) on conflict (pchar) do update set weapon=$2, armor=$3, shield=$4, unit0=$5, unit1=$6, unit2=$7, unit3=$8, mag=$9"#) - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(equips.weapon.map(|i| i.0 as i32)) .bind(equips.armor.map(|i| i.0 as i32)) .bind(equips.shield.map(|i| i.0 as i32)) @@ -569,7 +569,7 @@ async fn set_character_equips(conn: &mut sqlx::PgConnection, char_id: &Character async fn set_character_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId, meseta: Meseta) -> Result<(), GatewayError> { sqlx::query("insert into character_meseta values ($1, $2) on conflict (pchar) do update set meseta = $2") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(meseta.0 as i32) .execute(conn) .await?; @@ -581,7 +581,7 @@ async fn get_character_meseta(conn: &mut sqlx::PgConnection, char_id: &Character #[derive(sqlx::FromRow)] struct PgMeseta(i32); let meseta = sqlx::query_as::<_, PgMeseta>(r#"select meseta from character_meseta where pchar = $1"#) - .bind(char_id.0) + .bind(char_id.0 as i32) .fetch_one(conn) .await?; Ok(Meseta(meseta.0 as u32)) @@ -592,7 +592,7 @@ async fn set_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit match bank_identifier { BankIdentifier::Character => { sqlx::query("insert into bank_meseta values ($1, '', $2) on conflict (pchar, bank) do update set meseta = $2") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(meseta.0 as i32) .execute(conn) .await?; @@ -602,7 +602,7 @@ async fn set_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit select player_character.user_account, $2, $3 from player_character where player_character.id = $1 on conflict (user_account, name) do update set meseta = $3") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(&bank_name.0) .bind(meseta.0 as i32) .execute(conn) @@ -621,7 +621,7 @@ async fn get_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit let meseta = match bank_identifier { BankIdentifier::Character => { sqlx::query_as::<_, PgMeseta>(r#"select meseta from bank_meseta where pchar = $1"#) - .bind(char_id.0) + .bind(char_id.0 as i32) .fetch_one(conn) .await? }, @@ -629,7 +629,7 @@ async fn get_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit sqlx::query_as::<_, PgMeseta>(r#"select shared_bank_meseta.meseta from shared_bank_meseta join player_character on shared_bank_meseta.user_account = player_character.user_account where player_character.id = $1 and shared_bank_meseta.name = $2"#) - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(&bank_name.0) .fetch_optional(conn) .await? @@ -642,8 +642,8 @@ async fn get_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit async fn create_trade(conn: &mut sqlx::PgConnection, char_id1: &CharacterEntityId, char_id2: &CharacterEntityId) -> Result { let trade = sqlx::query_as::<_, PgTradeEntity>(r#"insert into trades (character1, character2) values ($1, $2) returning *;"#) - .bind(char_id1.0) - .bind(char_id2.0) + .bind(char_id1.0 as i32) + .bind(char_id2.0 as i32) .fetch_one(conn) .await?; Ok(trade.into()) @@ -652,8 +652,8 @@ async fn create_trade(conn: &mut sqlx::PgConnection, char_id1: &CharacterEntityI async fn set_character_playtime(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> { sqlx::query(r#"update player_character set playtime=$2 where id=$1;"#) - .bind(char_id.0) - .bind(playtime) + .bind(char_id.0 as i32) + .bind(playtime as i32) .execute(conn) .await?; Ok(()) @@ -674,7 +674,7 @@ async fn create_room(conn: &mut sqlx::PgConnection, room: NewRoomEntity) -> Resu async fn add_room_note(conn: &mut sqlx::PgConnection, room_id: RoomEntityId, note: RoomNote) -> Result<(), GatewayError> { sqlx::query("insert into room_note (room, note) values ($1, $2)") - .bind(room_id.0) + .bind(room_id.0 as i32) .bind(sqlx::types::Json(note)) .execute(conn) .await?; -- 2.36.0 From a28fdb43cd252141d50e9e90b94de80e2673f64d Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 18 Feb 2023 16:20:26 -0700 Subject: [PATCH 11/58] char is not "char" reeeeee --- src/entity/gateway/postgres/migrations/V0012__room.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/entity/gateway/postgres/migrations/V0012__room.sql b/src/entity/gateway/postgres/migrations/V0012__room.sql index 750493c..1064ea1 100644 --- a/src/entity/gateway/postgres/migrations/V0012__room.sql +++ b/src/entity/gateway/postgres/migrations/V0012__room.sql @@ -1,11 +1,11 @@ -create table room { +create table room ( id serial primary key not null, name varchar(32) not null, section_id char not null, mode char not null, episode char not null, - difficulty char not null, -}; + difficulty char not null +); create table room_note ( room integer references room (id) not null, -- 2.36.0 From 9b193496f291d20bf75dfe94e2ba5d6600c71b07 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 18 Feb 2023 17:27:18 -0700 Subject: [PATCH 12/58] update cargolock --- Cargo.lock | 71 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dfff310..4c67963 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,11 +145,11 @@ dependencies = [ [[package]] name = "async-native-tls" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9e7a929bd34c68a82d58a4de7f86fffdaf97fb2af850162a7bb19dd7269b33" +checksum = "d57d4cec3c647232e1094dc013546c0b33ce785d8aeb251e1f20dfaf8a9a13fe" dependencies = [ - "async-std", + "futures-util", "native-tls", "thiserror", "url", @@ -231,9 +231,9 @@ dependencies = [ [[package]] name = "atoi" -version = "0.4.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" +checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" dependencies = [ "num-traits", ] @@ -483,18 +483,18 @@ dependencies = [ [[package]] name = "crc" -version = "2.1.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" dependencies = [ "crc-catalog", ] [[package]] name = "crc-catalog" -version = "1.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" [[package]] name = "crossbeam-queue" @@ -581,10 +581,10 @@ dependencies = [ ] [[package]] -name = "dotenv" -version = "0.15.0" +name = "dotenvy" +version = "0.15.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0" [[package]] name = "either" @@ -892,17 +892,23 @@ name = "hashbrown" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash", ] [[package]] name = "hashlink" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" dependencies = [ - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -974,7 +980,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg 1.1.0", - "hashbrown", + "hashbrown 0.11.2", ] [[package]] @@ -1818,10 +1824,10 @@ dependencies = [ ] [[package]] -name = "sha-1" -version = "0.10.0" +name = "sha1" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +checksum = "006769ba83e921b3085caa8334186b00cf92b4cb1a6cf4632fbccc8eff5c7549" dependencies = [ "cfg-if", "cpufeatures", @@ -1888,9 +1894,9 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.1.8" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" +checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" dependencies = [ "itertools", "nom", @@ -1899,9 +1905,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.5.13" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" +checksum = "9249290c05928352f71c077cc44a464d880c63f26f7534728cca008e135c0428" dependencies = [ "sqlx-core", "sqlx-macros", @@ -1909,9 +1915,9 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.5.13" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5" +checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105" dependencies = [ "ahash", "atoi", @@ -1920,9 +1926,10 @@ dependencies = [ "byteorder", "bytes", "chrono", - "crc 2.1.0", + "crc 3.0.1", "crossbeam-queue", "dirs", + "dotenvy", "either", "event-listener", "futures-channel", @@ -1945,7 +1952,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "sha-1", + "sha1", "sha2", "smallvec", "sqlformat", @@ -1958,11 +1965,11 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.5.13" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0fba2b0cae21fc00fe6046f8baa4c7fcb49e379f0f592b04696607f69ed2e1" +checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9" dependencies = [ - "dotenv", + "dotenvy", "either", "heck 0.4.0", "once_cell", @@ -1978,9 +1985,9 @@ dependencies = [ [[package]] name = "sqlx-rt" -version = "0.5.13" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae" +checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396" dependencies = [ "async-native-tls", "async-std", -- 2.36.0 From d466e6e613059edd06486c3d626facb237a179f7 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 18 Feb 2023 17:34:54 -0700 Subject: [PATCH 13/58] roomnotery --- src/ship/packet/handler/lobby.rs | 14 ++++++++++- src/ship/packet/handler/room.rs | 40 +++++++++++++++++++++----------- src/ship/ship.rs | 15 ++++++++++-- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/src/ship/packet/handler/lobby.rs b/src/ship/packet/handler/lobby.rs index 9d7ca08..d5506c4 100644 --- a/src/ship/packet/handler/lobby.rs +++ b/src/ship/packet/handler/lobby.rs @@ -8,6 +8,7 @@ use crate::ship::location::{ClientLocation, LobbyId, RoomLobby, ClientLocationEr use crate::ship::packet; use crate::ship::items::state::ItemState; use crate::entity::gateway::EntityGateway; +use crate::entity::room::RoomNote; use crate::ship::map::MapArea; use futures::future::join_all; @@ -89,14 +90,25 @@ where } }, RoomLobby::Room(old_room) => { + let room_entity_id = rooms.with(old_room, |room| Box::pin(async { + room.room_id + })).await?; if client_location.get_client_neighbors(id).await?.is_empty() { rooms.remove(old_room).await; } + + let character_id = clients.with(id, |client| Box::pin(async { + client.character.id + })).await?; clients.with(id, |client| { let mut item_state = item_state.clone(); + let mut entity_gateway = entity_gateway.clone(); Box::pin(async move { item_state.remove_character_from_room(&client.character).await; - })}).await?; + entity_gateway.add_room_note(room_entity_id, RoomNote::PlayerLeave { + character_id + }).await + })}).await??; }, } let leave_lobby = packet::builder::lobby::remove_from_lobby(id, client_location).await?; diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index ca9ea5b..466a58a 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -9,7 +9,7 @@ use crate::common::serverstate::ClientId; use crate::common::leveltable::LEVEL_TABLE; use crate::entity::gateway::EntityGateway; use crate::entity::character::SectionID; -use crate::entity::room::{RoomEntity, RoomEntityId, NewRoomEntity, RoomEntityMode}; +use crate::entity::room::{RoomEntity, RoomEntityId, NewRoomEntity, RoomEntityMode, RoomNote}; use crate::ship::drops::DropTable; use crate::ship::ship::{SendShipPacket, Clients, ShipEvent}; use crate::ship::room::{Rooms, Episode, Difficulty, RoomState, RoomMode}; @@ -57,7 +57,6 @@ where let room_id = client_location.create_new_room(id).await?; let new_area_client = client_location.get_local_client(id).await?; - let name = String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).to_string(); let mode = match (create_room.battle, create_room.challenge, create_room.single_player) { (1, 0, 0) => RoomEntityMode::Battle, @@ -81,6 +80,10 @@ where difficulty, }).await?; + entity_gateway.add_room_note(room_entity.id, RoomNote::Create { + character_id: client.character.id, + }).await?; + let mut room = RoomState::new(room_entity.id, mode, episode, difficulty, client.character.section_id, name, create_room.password, event, map_builder, drop_table_builder)?; @@ -121,14 +124,18 @@ pub async fn room_name_request(id: ClientId, } } -pub async fn join_room(id: ClientId, - pkt: MenuSelect, - client_location: &mut ClientLocation, - clients: &Clients, - item_state: &mut ItemState, - rooms: &Rooms, - event: ShipEvent) - -> Result, anyhow::Error> { +pub async fn join_room(id: ClientId, + pkt: MenuSelect, + entity_gateway: &mut EG, + client_location: &mut ClientLocation, + clients: &Clients, + item_state: &mut ItemState, + rooms: &Rooms, + event: ShipEvent) + -> Result, anyhow::Error> +where + EG: EntityGateway + Clone + 'static, +{ let room_id = RoomId(pkt.item as usize); if !rooms.exists(room_id).await { return Ok(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("This room no longer exists!".into())))]) @@ -136,8 +143,8 @@ pub async fn join_room(id: ClientId, let level = clients.with(id, |client| Box::pin(async move { LEVEL_TABLE.get_level_from_exp(client.character.char_class, client.character.exp) })).await?; - let (difficulty, bursting) = rooms.with(room_id, |room| Box::pin(async move { - (room.mode.difficulty(), room.bursting) + let (difficulty, bursting, room_entity_id) = rooms.with(room_id, |room| Box::pin(async move { + (room.mode.difficulty(), room.bursting, room.room_id) })).await?; match difficulty { @@ -166,9 +173,14 @@ pub async fn join_room(id: ClientId, clients.with(id, |client| { let mut item_state = item_state.clone(); + let mut entity_gateway = entity_gateway.clone(); Box::pin(async move { + entity_gateway.add_room_note(room_entity_id, RoomNote::PlayerJoin { + character_id: client.character.id, + }).await?; item_state.add_character_to_room(room_id, &client.character, area_client).await; - })}).await?; + Ok::<_, anyhow::Error>(()) + })}).await??; let join_room = rooms.with(room_id, |room| { let clients = clients.clone(); @@ -185,7 +197,7 @@ pub async fn join_room(id: ClientId, rooms.with_mut(room_id, |room| Box::pin(async move { room.bursting = true; })).await?; - + Ok(vec![(id, SendShipPacket::JoinRoom(join_room))] .into_iter() .chain(original_room_clients.into_iter() diff --git a/src/ship/ship.rs b/src/ship/ship.rs index e4d94c8..8d9e4e0 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -20,6 +20,7 @@ use crate::common::interserver::{AuthToken, Ship, ServerId, InterserverActor, Lo use crate::login::character::SHIP_MENU_ID; use crate::entity::gateway::{EntityGateway, GatewayError}; use crate::entity::character::SectionID; +use crate::entity::room::RoomNote; use crate::ship::location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; use crate::ship::drops::DropTable; use crate::ship::items; @@ -700,7 +701,7 @@ impl ServerState for ShipServerState { let select_block = handler::lobby::block_selected(id, menuselect, &self.clients, &self.item_state).await?.into_iter(); leave_lobby.chain(select_block).collect() } - ROOM_MENU_ID => handler::room::join_room(id, menuselect, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await?, + ROOM_MENU_ID => handler::room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await?, QUEST_CATEGORY_MENU_ID => handler::quest::select_quest_category(id, menuselect, &block.client_location, &block.rooms).await?, _ => unreachable!(), } @@ -725,7 +726,7 @@ impl ServerState for ShipServerState { menu: room_password_req.menu, item: room_password_req.item, }; - handler::room::join_room(id, menuselect, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await? + handler::room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await? } else { vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("Incorrect password".into())))] @@ -853,6 +854,16 @@ impl ServerState for ShipServerState { let pkt = match block.client_location.get_area(id).await? { RoomLobby::Room(room) => { + let character_id = self.clients.with(id, |client| Box::pin(async { + client.character.id + })).await?; + block.rooms.with(room, |room| { + let mut entity_gateway = self.entity_gateway.clone(); + Box::pin(async move { + entity_gateway.add_room_note(room.room_id, RoomNote::PlayerJoin { + character_id: character_id, + }).await + })}).await; if neighbors.is_empty() { block.rooms.remove(room).await; } -- 2.36.0 From cd0d7f00e58b350f8e8039aca01c4b12581c3920 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 18 Feb 2023 17:35:05 -0700 Subject: [PATCH 14/58] small cleanup --- src/ship/quests.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ship/quests.rs b/src/ship/quests.rs index e0b8c8c..4f5eb26 100644 --- a/src/ship/quests.rs +++ b/src/ship/quests.rs @@ -271,10 +271,10 @@ pub fn load_quests_path(mut quest_path: PathBuf) -> Result Result { match mode { - RoomMode::Single {episode, difficulty } => { + RoomMode::Single {episode, .. } => { load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "single", "quests.toml"])) }, - RoomMode::Multi {episode, difficulty } => { + RoomMode::Multi {episode, .. } => { load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "multi", "quests.toml"])) }, _ => { @@ -286,10 +286,10 @@ pub fn load_standard_quests(mode: RoomMode) -> Result pub fn load_government_quests(mode: RoomMode) -> Result { match mode { - RoomMode::Single {episode, difficulty } => { + RoomMode::Single {episode, .. } => { load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "government", "quests.toml"])) }, - RoomMode::Multi {episode, difficulty } => { + RoomMode::Multi {episode, .. } => { load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "government", "quests.toml"])) }, _ => { -- 2.36.0 From 683ecc93837bf5e6b2a23df1c9965f8d37fc3aac Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 18 Feb 2023 17:55:07 -0700 Subject: [PATCH 15/58] clippy --- src/entity/room.rs | 30 +----------------------------- src/ship/items/actions.rs | 1 - src/ship/items/tasks.rs | 4 ++-- src/ship/packet/handler/quest.rs | 2 +- src/ship/packet/handler/room.rs | 3 ++- src/ship/room.rs | 4 ++-- src/ship/ship.rs | 2 +- 7 files changed, 9 insertions(+), 37 deletions(-) diff --git a/src/entity/room.rs b/src/entity/room.rs index d59327e..a5eeea4 100644 --- a/src/entity/room.rs +++ b/src/entity/room.rs @@ -2,7 +2,7 @@ use serde::{Serialize, Deserialize}; use crate::entity::character::{CharacterEntityId, SectionID}; -use crate::ship::room::{Episode, Difficulty, RoomMode}; +use crate::ship::room::{Episode, Difficulty}; #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)] @@ -62,34 +62,6 @@ pub struct NewRoomEntity { pub difficulty: Difficulty, } -impl NewRoomEntity { - fn new(name: String, section_id: SectionID, mode: RoomMode) -> NewRoomEntity { - NewRoomEntity { - name: name, - section_id: section_id, - mode: match mode { - RoomMode::Single {..} => RoomEntityMode::Single, - RoomMode::Multi {..} => RoomEntityMode::Multi, - RoomMode::Challenge {..} => RoomEntityMode::Challenge, - RoomMode::Battle {..} => RoomEntityMode::Battle, - }, - episode: match mode { - RoomMode::Single { episode, .. } => episode, - RoomMode::Multi { episode, ..} => episode , - RoomMode::Challenge { episode, ..} => episode, - RoomMode::Battle { episode, ..} => episode, - }, - difficulty: match mode { - RoomMode::Single { difficulty, .. } => difficulty, - RoomMode::Multi { difficulty, ..} => difficulty , - RoomMode::Challenge {..} => Difficulty::Normal, - RoomMode::Battle { difficulty, ..} => difficulty, - }, - } - } -} - - #[derive(Debug, Copy, Clone, Serialize)] pub enum RoomNote { Create { diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index ad36f52..849ad0d 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -909,7 +909,6 @@ where pub(super) fn convert_item_drop_to_floor_item<'a, EG, TR>( - character_id: CharacterEntityId, item_drop: ItemDrop, ) -> impl Fn((ItemStateProxy, TR), ()) -> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + Clone diff --git a/src/ship/items/tasks.rs b/src/ship/items/tasks.rs index d8603f0..0c3f948 100644 --- a/src/ship/items/tasks.rs +++ b/src/ship/items/tasks.rs @@ -477,7 +477,7 @@ where entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default() - .act(actions::convert_item_drop_to_floor_item(character_id, item_drop)) + .act(actions::convert_item_drop_to_floor_item(item_drop)) .act(actions::item_note_enemy_drop(character_id, room_id, monster_type)) .act(actions::add_item_to_local_floor(character_id)) .commit((item_state_proxy, transaction)) @@ -501,7 +501,7 @@ where entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default() - .act(actions::convert_item_drop_to_floor_item(character_id, item_drop)) + .act(actions::convert_item_drop_to_floor_item(item_drop)) .act(actions::item_note_box_drop(character_id, room_id)) .act(actions::add_item_to_local_floor(character_id)) .commit((item_state_proxy, transaction)) diff --git a/src/ship/packet/handler/quest.rs b/src/ship/packet/handler/quest.rs index 3dee2ff..1c8c31e 100644 --- a/src/ship/packet/handler/quest.rs +++ b/src/ship/packet/handler/quest.rs @@ -3,7 +3,7 @@ use futures::stream::{FuturesOrdered, StreamExt}; use libpso::packet::ship::*; use crate::common::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, ShipError, Clients, ShipEvent}; -use crate::ship::room::{Rooms, QuestCategoryType}; +use crate::ship::room::Rooms; use crate::ship::map::enemy::RareMonsterAppearTable; use crate::ship::location::{ClientLocation}; use crate::ship::packet::builder::quest; diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 466a58a..9198c63 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -9,7 +9,7 @@ use crate::common::serverstate::ClientId; use crate::common::leveltable::LEVEL_TABLE; use crate::entity::gateway::EntityGateway; use crate::entity::character::SectionID; -use crate::entity::room::{RoomEntity, RoomEntityId, NewRoomEntity, RoomEntityMode, RoomNote}; +use crate::entity::room::{NewRoomEntity, RoomEntityMode, RoomNote}; use crate::ship::drops::DropTable; use crate::ship::ship::{SendShipPacket, Clients, ShipEvent}; use crate::ship::room::{Rooms, Episode, Difficulty, RoomState, RoomMode}; @@ -124,6 +124,7 @@ pub async fn room_name_request(id: ClientId, } } +#[allow(clippy::too_many_arguments)] pub async fn join_room(id: ClientId, pkt: MenuSelect, entity_gateway: &mut EG, diff --git a/src/ship/room.rs b/src/ship/room.rs index 69820b1..b3a03c2 100644 --- a/src/ship/room.rs +++ b/src/ship/room.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; -use std::convert::{From, Into, TryFrom, TryInto}; -use std::path::PathBuf; +use std::convert::{From, Into, TryFrom}; use async_std::sync::{Arc, RwLock, RwLockReadGuard}; use futures::future::BoxFuture; use futures::stream::{FuturesOrdered, Stream}; @@ -361,6 +360,7 @@ impl RoomState { } } + #[allow(clippy::too_many_arguments)] pub fn new (room_id: RoomEntityId, mode: RoomEntityMode, episode: Episode, diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 8d9e4e0..554d9d5 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -861,7 +861,7 @@ impl ServerState for ShipServerState { let mut entity_gateway = self.entity_gateway.clone(); Box::pin(async move { entity_gateway.add_room_note(room.room_id, RoomNote::PlayerJoin { - character_id: character_id, + character_id, }).await })}).await; if neighbors.is_empty() { -- 2.36.0 From 7f77063ed7ec7d6bfb9fb7f19aa62ab9ed6ce96d Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 18 Feb 2023 18:01:04 -0700 Subject: [PATCH 16/58] remove the cargo.lock it only caused suffering --- Cargo.lock | 2395 ---------------------------------------------------- 1 file changed, 2395 deletions(-) delete mode 100644 Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 4c67963..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,2395 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ages-prs" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "089e6d1d25d8975ac1bf2da0d1556ebdb99fee1a9aec6467d138a6e090b92ff4" -dependencies = [ - "libflate_lz77", -] - -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom 0.2.6", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" -dependencies = [ - "backtrace", -] - -[[package]] -name = "async-attributes" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "async-channel" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-executor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "once_cell", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c290043c9a95b05d45e952fb6383c67bcb61471f60cfa21e890dba6654234f43" -dependencies = [ - "async-channel", - "async-executor", - "async-io", - "async-mutex", - "blocking", - "futures-lite", - "num_cpus", - "once_cell", -] - -[[package]] -name = "async-io" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" -dependencies = [ - "concurrent-queue", - "futures-lite", - "libc", - "log", - "once_cell", - "parking", - "polling", - "slab", - "socket2", - "waker-fn", - "winapi", -] - -[[package]] -name = "async-lock" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-mutex" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-native-tls" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d57d4cec3c647232e1094dc013546c0b33ce785d8aeb251e1f20dfaf8a9a13fe" -dependencies = [ - "futures-util", - "native-tls", - "thiserror", - "url", -] - -[[package]] -name = "async-process" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83137067e3a2a6a06d67168e49e68a0957d215410473a740cea95a2425c0b7c6" -dependencies = [ - "async-io", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "libc", - "once_cell", - "signal-hook", - "winapi", -] - -[[package]] -name = "async-recursion" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cda8f4bcc10624c4e85bc66b3f452cca98cfa5ca002dc83a16aad2367641bea" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-std" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52580991739c5cdb36cde8b2a516371c0a3b70dda36d916cc08b82372916808c" -dependencies = [ - "async-attributes", - "async-channel", - "async-global-executor", - "async-io", - "async-lock", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "num_cpus", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9" - -[[package]] -name = "async-trait" -version = "0.1.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atoi" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" -dependencies = [ - "num-traits", -] - -[[package]] -name = "atomic-waker" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.1.0", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "barrel" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d67c978b1322c8031145b1f6c236fc371292f52c565bc96018b2971afcbffe1" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "bcrypt" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f691e63585950d8c1c43644d11bab9073e40f5060dd2822734ae7c3dc69a3a80" -dependencies = [ - "base64", - "blowfish", - "getrandom 0.2.6", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "block-buffer" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" -dependencies = [ - "generic-array", -] - -[[package]] -name = "blocking" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" -dependencies = [ - "async-channel", - "async-task", - "atomic-waker", - "fastrand", - "futures-lite", - "once_cell", -] - -[[package]] -name = "blowfish" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3ff3fc1de48c1ac2e3341c4df38b0d1bfb8fdf04632a187c8b75aaa319a7ab" -dependencies = [ - "byteorder", - "cipher", - "opaque-debug", -] - -[[package]] -name = "build_const" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7" - -[[package]] -name = "bumpalo" -version = "3.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cache-padded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time", - "winapi", -] - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "colored" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" -dependencies = [ - "atty", - "lazy_static", - "winapi", -] - -[[package]] -name = "concurrent-queue" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" -dependencies = [ - "cache-padded", -] - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crc" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" -dependencies = [ - "build_const", -] - -[[package]] -name = "crc" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" - -[[package]] -name = "crossbeam-queue" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" -dependencies = [ - "cfg-if", - "lazy_static", -] - -[[package]] -name = "crypto-common" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ctor" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn", -] - -[[package]] -name = "digest" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dotenvy" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0" - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "elseware" -version = "0.1.0" -dependencies = [ - "ages-prs", - "anyhow", - "async-recursion", - "async-std", - "async-trait", - "barrel", - "bcrypt", - "byteorder", - "chrono", - "crc 1.8.1", - "derive_more", - "enum-utils", - "fern", - "futures", - "lazy_static", - "libpso", - "log", - "rand 0.7.3", - "rand_chacha 0.2.2", - "refinery", - "ron", - "serde", - "serde_json", - "sqlx", - "strum", - "strum_macros", - "thiserror", - "toml", -] - -[[package]] -name = "enum-utils" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed327f716d0d351d86c9fd3398d20ee39ad8f681873cc081da2ca1c10fed398a" -dependencies = [ - "enum-utils-from-str", - "failure", - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "enum-utils-from-str" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d49be08bad6e4ca87b2b8e74146987d4e5cb3b7512efa50ef505b51a22227ee1" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "event-listener" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" - -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", -] - -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fastrand" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" -dependencies = [ - "instant", -] - -[[package]] -name = "fern" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e69ab0d5aca163e388c3a49d284fed6c3d0810700e77c5ae2756a50ec1a4daaa" -dependencies = [ - "chrono", - "colored", - "log", -] - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "futures" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" - -[[package]] -name = "futures-executor" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-intrusive" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e" -dependencies = [ - "futures-core", - "lock_api", - "parking_lot", -] - -[[package]] -name = "futures-io" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" - -[[package]] -name = "futures-lite" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] -name = "futures-macro" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" - -[[package]] -name = "futures-task" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" - -[[package]] -name = "futures-util" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "gimli" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" - -[[package]] -name = "gloo-timers" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashlink" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" -dependencies = [ - "hashbrown 0.12.3", -] - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkdf" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" -dependencies = [ - "autocfg 1.1.0", - "hashbrown 0.11.2", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" - -[[package]] -name = "js-sys" -version = "0.3.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" - -[[package]] -name = "libflate_lz77" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739e9d7726dc32173fed2d69d17eef3c54682169e4e20ff1d0a45dcd37063cef" - -[[package]] -name = "libpso" -version = "0.1.0" -dependencies = [ - "chrono", - "psopacket", - "rand 0.6.5", -] - -[[package]] -name = "lock_api" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" -dependencies = [ - "autocfg 1.1.0", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" -dependencies = [ - "cfg-if", - "value-bag", -] - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "md-5" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658646b21e0b72f7866c7038ab086d3d5e1cd6271f060fd37defb241949d0582" -dependencies = [ - "digest", -] - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "wasi 0.11.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "native-tls" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nom" -version = "7.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg 1.1.0", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg 1.1.0", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.28.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40bec70ba014595f99f7aa110b84331ffe1ee9aece7fe6f387cc7e3ecda4d456" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" -dependencies = [ - "autocfg 1.1.0", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "parking" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "paste" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "phf" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" -dependencies = [ - "phf_shared", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" - -[[package]] -name = "polling" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" -dependencies = [ - "cfg-if", - "libc", - "log", - "wepoll-ffi", - "winapi", -] - -[[package]] -name = "postgres" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb76d6535496f633fa799bb872ffb4790e9cbdedda9d35564ca0252f930c0dd5" -dependencies = [ - "bytes", - "fallible-iterator", - "futures", - "log", - "tokio", - "tokio-postgres", -] - -[[package]] -name = "postgres-protocol" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ec03bce71f18b4a27c4c64c6ba2ddf74686d69b91d8714fb32ead3adaed713" -dependencies = [ - "base64", - "byteorder", - "bytes", - "fallible-iterator", - "hmac", - "md-5", - "memchr", - "rand 0.8.5", - "sha2", - "stringprep", -] - -[[package]] -name = "postgres-types" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04619f94ba0cc80999f4fc7073607cb825bc739a883cb6d20900fc5e009d6b0d" -dependencies = [ - "bytes", - "fallible-iterator", - "postgres-protocol", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" - -[[package]] -name = "proc-macro2" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "psopacket" -version = "1.0.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc 0.1.0", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.6", -] - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "redox_syscall" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom 0.2.6", - "redox_syscall", - "thiserror", -] - -[[package]] -name = "refinery" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e29bd9c881127d714f4b5b9fdd9ea7651f3dd254922e959a10f6ada620e841da" -dependencies = [ - "refinery-core", - "refinery-macros", -] - -[[package]] -name = "refinery-core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53260bc01535ea10c553ce0fc410609ba2dc0a9f4c9b4503e0af842dd4a6f89d" -dependencies = [ - "async-trait", - "cfg-if", - "chrono", - "lazy_static", - "log", - "postgres", - "regex", - "serde", - "siphasher", - "thiserror", - "toml", - "url", - "walkdir", -] - -[[package]] -name = "refinery-macros" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a79ff62c9b674b62c06a09cc8becf06cbafba9952afa1d8174e7e15f2c4ed43" -dependencies = [ - "proc-macro2", - "quote", - "refinery-core", - "regex", - "syn", -] - -[[package]] -name = "regex" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "ron" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b861ecaade43ac97886a512b360d01d66be9f41f3c61088b42cedf92e03d678" -dependencies = [ - "base64", - "bitflags", - "serde", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "ryu" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" -dependencies = [ - "lazy_static", - "winapi", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "security-framework" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4" - -[[package]] -name = "serde" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_derive_internals" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006769ba83e921b3085caa8334186b00cf92b4cb1a6cf4632fbccc8eff5c7549" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "signal-hook" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "siphasher" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" - -[[package]] -name = "slab" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" - -[[package]] -name = "smallvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" - -[[package]] -name = "socket2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "sqlformat" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" -dependencies = [ - "itertools", - "nom", - "unicode_categories", -] - -[[package]] -name = "sqlx" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9249290c05928352f71c077cc44a464d880c63f26f7534728cca008e135c0428" -dependencies = [ - "sqlx-core", - "sqlx-macros", -] - -[[package]] -name = "sqlx-core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105" -dependencies = [ - "ahash", - "atoi", - "base64", - "bitflags", - "byteorder", - "bytes", - "chrono", - "crc 3.0.1", - "crossbeam-queue", - "dirs", - "dotenvy", - "either", - "event-listener", - "futures-channel", - "futures-core", - "futures-intrusive", - "futures-util", - "hashlink", - "hex", - "hkdf", - "hmac", - "indexmap", - "itoa", - "libc", - "log", - "md-5", - "memchr", - "once_cell", - "paste", - "percent-encoding", - "rand 0.8.5", - "serde", - "serde_json", - "sha1", - "sha2", - "smallvec", - "sqlformat", - "sqlx-rt", - "stringprep", - "thiserror", - "url", - "whoami", -] - -[[package]] -name = "sqlx-macros" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9" -dependencies = [ - "dotenvy", - "either", - "heck 0.4.0", - "once_cell", - "proc-macro2", - "quote", - "serde_json", - "sha2", - "sqlx-core", - "sqlx-rt", - "syn", - "url", -] - -[[package]] -name = "sqlx-rt" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396" -dependencies = [ - "async-native-tls", - "async-std", - "native-tls", -] - -[[package]] -name = "stringprep" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "strum" -version = "0.19.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89a286a7e3b5720b9a477b23253bc50debac207c8d21505f8e70b36792f11b5" - -[[package]] -name = "strum_macros" -version = "0.19.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e61bb0be289045cb80bfce000512e32d09f8337e54c186725da381377ad1f8d5" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "thiserror" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f48b6d60512a392e34dbf7fd456249fd2de3c83669ab642e021903f4015185b" -dependencies = [ - "bytes", - "libc", - "memchr", - "mio", - "once_cell", - "pin-project-lite", - "socket2", - "winapi", -] - -[[package]] -name = "tokio-postgres" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6c8b33df661b548dcd8f9bf87debb8c56c05657ed291122e1188698c2ece95" -dependencies = [ - "async-trait", - "byteorder", - "bytes", - "fallible-iterator", - "futures", - "log", - "parking_lot", - "percent-encoding", - "phf", - "pin-project-lite", - "postgres-protocol", - "postgres-types", - "socket2", - "tokio", - "tokio-util", -] - -[[package]] -name = "tokio-util" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" -dependencies = [ - "serde", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "unicode-bidi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "value-bag" -version = "1.0.0-alpha.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" -dependencies = [ - "ctor", - "version_check", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" - -[[package]] -name = "web-sys" -version = "0.3.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "wepoll-ffi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" -dependencies = [ - "cc", -] - -[[package]] -name = "whoami" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524b58fa5a20a2fb3014dd6358b70e6579692a56ef6fce928834e488f42f65e8" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -- 2.36.0 From ad13f03cda44e986430aeb843f8ac5ef0467dccd Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 18 Feb 2023 18:06:40 -0700 Subject: [PATCH 17/58] oh yeah I kinda need this migration --- .../postgres/migrations/V0013__room2.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/entity/gateway/postgres/migrations/V0013__room2.sql diff --git a/src/entity/gateway/postgres/migrations/V0013__room2.sql b/src/entity/gateway/postgres/migrations/V0013__room2.sql new file mode 100644 index 0000000..f7a6a0a --- /dev/null +++ b/src/entity/gateway/postgres/migrations/V0013__room2.sql @@ -0,0 +1,17 @@ +drop table room_note; +drop table room; + +create table room ( + id serial primary key not null, + name varchar(32) not null, + section_id "char" not null, + mode "char" not null, + episode "char" not null, + difficulty "char" not null +); + +create table room_note ( + room integer references room (id) not null, + note jsonb not null, + created_at timestamptz default current_timestamp not null +); -- 2.36.0 From 08bcea7dcace0e5d2ad0b9de3c9c53074d32e03b Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 18 Feb 2023 18:09:11 -0700 Subject: [PATCH 18/58] this was hidden in some debug code I was skipping over --- src/ship/items/actions.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index 849ad0d..0c06691 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -551,7 +551,7 @@ where let mut transaction = tool.with_entity_id(transaction, |mut transaction, entity_id| { async move { transaction.gateway().add_item_note(&entity_id, ItemNote::FedToMag { - //character_id: character.id, + character_id: character.id, mag: mag_entity_id, }).await?; transaction.gateway().feed_mag(&mag_entity_id, &entity_id).await?; @@ -1241,4 +1241,4 @@ where Ok(((item_state, transaction), ())) }) } -} \ No newline at end of file +} -- 2.36.0 From 13ddbc8f5ee434f656ab060c088c4b14194ad5d5 Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 10 Nov 2023 13:35:16 -0700 Subject: [PATCH 19/58] get elseware to compile on latest rust --- src/lib.rs | 5 ++--- src/ship/items/floor.rs | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2c3d9c0..54fc603 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,11 @@ #![allow(clippy::type_complexity)] #![allow(incomplete_features)] #![feature(inline_const)] -#![feature(drain_filter)] +#![feature(extract_if)] #![feature(try_blocks)] -#![feature(once_cell)] #![feature(test)] #![feature(error_generic_member_access)] -#![feature(provide_any)] +#![feature(lazy_cell)] extern crate test; diff --git a/src/ship/items/floor.rs b/src/ship/items/floor.rs index c71b7fd..b0e968f 100644 --- a/src/ship/items/floor.rs +++ b/src/ship/items/floor.rs @@ -96,13 +96,13 @@ pub struct FloorState { impl FloorState { pub fn take_item(&mut self, item_id: &ClientItemId) -> Option { let item = self.local.0 - .drain_filter(|item| { + .extract_if(|item| { item.item_id == *item_id }) .next(); item.or_else(|| { self.shared.0 - .drain_filter(|item| { + .extract_if(|item| { item.item_id == *item_id }) .next() -- 2.36.0 From d158ac1d7f20b5cd05f627e01eb21cda3368190a Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 10 Nov 2023 21:37:23 -0700 Subject: [PATCH 20/58] break out entity and maps into separate crates --- Cargo.toml | 48 +++- common/Cargo.toml | 8 + common/src/lib.rs | 0 entity/Cargo.toml | 57 +++++ {src/entity => entity/src}/account.rs | 0 {src/entity => entity/src}/character.rs | 4 +- .../src}/gateway/entitygateway.rs | 8 +- .../entity => entity/src}/gateway/inmemory.rs | 10 +- {src/entity => entity/src}/gateway/mod.rs | 0 .../postgres/migrations/V0001__initial.sql | 0 .../postgres/migrations/V0002__equips.sql | 0 .../postgres/migrations/V0003__item_notes.sql | 0 .../postgres/migrations/V0004__meseta.sql | 0 .../postgres/migrations/V0005__trade.sql | 0 .../postgres/migrations/V0006__playtime.sql | 0 .../migrations/V0007__player_keyconfig.sql | 0 .../migrations/V0008__playtime_not_null.sql | 0 .../migrations/V0009__no_player_keyconfig.sql | 0 .../V0010__char_create_timestamp.sql | 0 .../migrations/V0011__shared_bank.sql | 0 .../postgres/migrations/V0012__room.sql | 0 .../postgres/migrations/V0013__room2.sql | 0 entity/src/gateway/postgres/migrations/mod.rs | 3 + .../src}/gateway/postgres/mod.rs | 0 .../src}/gateway/postgres/models.rs | 14 +- .../src}/gateway/postgres/postgres.rs | 14 +- {src/entity => entity/src}/item/armor.rs | 2 +- {src/entity => entity/src}/item/esweapon.rs | 0 {src/entity => entity/src}/item/mag.rs | 8 +- {src/entity => entity/src}/item/mod.rs | 30 +-- {src/entity => entity/src}/item/shield.rs | 0 {src/entity => entity/src}/item/tech.rs | 0 {src/entity => entity/src}/item/tool.rs | 0 {src/entity => entity/src}/item/unit.rs | 0 {src/entity => entity/src}/item/weapon.rs | 2 +- src/entity/mod.rs => entity/src/lib.rs | 0 {src/entity => entity/src}/room.rs | 4 +- entity/src/team.rs | 31 +++ maps/Cargo.toml | 15 ++ {src/ship/map => maps/src}/area.rs | 2 +- {src/ship/map => maps/src}/enemy.rs | 43 ++-- maps/src/lib.rs | 7 + {src/ship/map => maps/src}/maps.rs | 18 +- maps/src/monster.rs | 212 ++++++++++++++++++ {src/ship/map => maps/src}/object.rs | 8 +- maps/src/room.rs | 150 +++++++++++++ {src/ship/map => maps/src}/variant.rs | 3 +- networking/Cargo.toml | 4 + networking/src/lib.rs | 0 src/bin/login.rs | 2 +- src/bin/main.rs | 10 +- src/bin/ship.rs | 2 +- src/common/interserver.rs | 4 +- src/common/leveltable.rs | 2 +- src/common/mainloop/interserver.rs | 3 +- src/entity/gateway/postgres/migrations/mod.rs | 3 - src/lib.rs | 2 +- src/login/character.rs | 44 ++-- src/login/login.rs | 29 +-- src/ship/character.rs | 4 +- src/ship/chatcommand.rs | 4 +- src/ship/client.rs | 8 +- src/ship/drops/box_drop_table.rs | 12 +- src/ship/drops/generic_armor.rs | 10 +- src/ship/drops/generic_shield.rs | 10 +- src/ship/drops/generic_unit.rs | 10 +- src/ship/drops/generic_weapon.rs | 10 +- src/ship/drops/mod.rs | 46 ++-- src/ship/drops/rare_drop_table.rs | 20 +- src/ship/drops/tech_table.rs | 8 +- src/ship/drops/tool_table.rs | 12 +- src/ship/item_stats.rs | 14 +- src/ship/items/actions.rs | 16 +- src/ship/items/apply_item.rs | 14 +- src/ship/items/bank.rs | 6 +- src/ship/items/floor.rs | 8 +- src/ship/items/inventory.rs | 10 +- src/ship/items/state.rs | 12 +- src/ship/items/tasks.rs | 14 +- src/ship/map/mod.rs | 12 - src/ship/mod.rs | 4 +- src/ship/packet/builder/message.rs | 2 +- src/ship/packet/handler/auth.rs | 2 +- src/ship/packet/handler/communication.rs | 2 +- src/ship/packet/handler/direct_message.rs | 4 +- src/ship/packet/handler/lobby.rs | 6 +- src/ship/packet/handler/message.rs | 4 +- src/ship/packet/handler/quest.rs | 4 +- src/ship/packet/handler/room.rs | 24 +- src/ship/packet/handler/settings.rs | 2 +- src/ship/packet/handler/trade.rs | 4 +- src/ship/quests.rs | 11 +- src/ship/room.rs | 168 +------------- src/ship/ship.rs | 143 ++++++------ src/ship/shops/armor.rs | 8 +- src/ship/shops/mod.rs | 2 +- src/ship/shops/tool.rs | 6 +- src/ship/shops/weapon.rs | 8 +- tests/common.rs | 12 +- tests/test_bank.rs | 4 +- tests/test_character.rs | 2 +- tests/test_exp_gain.rs | 12 +- tests/test_item_actions.rs | 4 +- tests/test_item_drop.rs | 15 +- tests/test_item_id.rs | 6 +- tests/test_item_pickup.rs | 4 +- tests/test_item_use.rs | 6 +- tests/test_mags.rs | 6 +- tests/test_rooms.rs | 4 +- tests/test_shops.rs | 6 +- tests/test_trade.rs | 10 +- 111 files changed, 989 insertions(+), 572 deletions(-) create mode 100644 common/Cargo.toml create mode 100644 common/src/lib.rs create mode 100644 entity/Cargo.toml rename {src/entity => entity/src}/account.rs (100%) rename {src/entity => entity/src}/character.rs (98%) rename {src/entity => entity/src}/gateway/entitygateway.rs (98%) rename {src/entity => entity/src}/gateway/inmemory.rs (99%) rename {src/entity => entity/src}/gateway/mod.rs (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0001__initial.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0002__equips.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0003__item_notes.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0004__meseta.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0005__trade.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0006__playtime.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0007__player_keyconfig.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0008__playtime_not_null.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0009__no_player_keyconfig.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0010__char_create_timestamp.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0011__shared_bank.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0012__room.sql (100%) rename {src/entity => entity/src}/gateway/postgres/migrations/V0013__room2.sql (100%) create mode 100644 entity/src/gateway/postgres/migrations/mod.rs rename {src/entity => entity/src}/gateway/postgres/mod.rs (100%) rename {src/entity => entity/src}/gateway/postgres/models.rs (99%) rename {src/entity => entity/src}/gateway/postgres/postgres.rs (99%) rename {src/entity => entity/src}/item/armor.rs (99%) rename {src/entity => entity/src}/item/esweapon.rs (100%) rename {src/entity => entity/src}/item/mag.rs (99%) rename {src/entity => entity/src}/item/mod.rs (84%) rename {src/entity => entity/src}/item/shield.rs (100%) rename {src/entity => entity/src}/item/tech.rs (100%) rename {src/entity => entity/src}/item/tool.rs (100%) rename {src/entity => entity/src}/item/unit.rs (100%) rename {src/entity => entity/src}/item/weapon.rs (99%) rename src/entity/mod.rs => entity/src/lib.rs (100%) rename {src/entity => entity/src}/room.rs (93%) create mode 100644 entity/src/team.rs create mode 100644 maps/Cargo.toml rename {src/ship/map => maps/src}/area.rs (99%) rename {src/ship/map => maps/src}/enemy.rs (93%) create mode 100644 maps/src/lib.rs rename {src/ship/map => maps/src}/maps.rs (97%) create mode 100644 maps/src/monster.rs rename {src/ship/map => maps/src}/object.rs (98%) create mode 100644 maps/src/room.rs rename {src/ship/map => maps/src}/variant.rs (99%) create mode 100644 networking/Cargo.toml create mode 100644 networking/src/lib.rs delete mode 100644 src/entity/gateway/postgres/migrations/mod.rs delete mode 100644 src/ship/map/mod.rs diff --git a/Cargo.toml b/Cargo.toml index c2e511d..7561e6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,20 @@ version = "0.1.0" authors = ["Jake Probst "] edition = "2021" -[dependencies] +[workspace] +members = [ + "entity", + "maps", + "common", + "networking", +] + +[workspace.dependencies] libpso = { git = "http://git.sharnoth.com/jake/libpso" } +entity = { path = "./entity" } +maps = { path = "./maps" } +common = { path = "./common" } +networking = { path = "./networking" } async-std = { version = "1.9.0", features = ["unstable", "attributes"] } futures = "0.3.5" rand = "0.7.3" @@ -33,3 +45,37 @@ sqlx = { version = "0.6.2", features = ["runtime-async-std-native-tls", "postgre strum = "0.19.5" strum_macros = "0.19" anyhow = { version = "1.0.68", features = ["backtrace"] } + +[dependencies] +libpso = { git = "http://git.sharnoth.com/jake/libpso" } +entity = { path = "./entity" } +maps = { path = "./maps" } +common = { path = "./common" } +networking = { path = "./networking" } +async-std = { version = "1.9.0", features = ["unstable", "attributes"] } +futures = "0.3.5" +rand = "0.7.3" +rand_chacha = "0.2.2" +crc = "^1.0.0" +bcrypt = "0.10" +chrono = { workspace = true } +serde = "*" +serde_json = "*" +ron = "*" +toml = "*" +log = "*" +fern = { version = "0.5", features = ["colored"] } +byteorder = "1" +enum-utils = "0.1.2" +derive_more = { version = "0.99.3", features = ["display"]} +thiserror = "1.0.37" +ages-prs = "0.1" +async-trait = "0.1.51" +async-recursion= "1.0.0" +lazy_static = "1.4.0" +barrel = { version = "0.6.5", features = ["pg"] } +refinery = { version = "0.5.0", features = ["postgres"] } +#sqlx = { version = "0.6.2", features = ["runtime-async-std-native-tls", "postgres", "json", "chrono"] } +strum = "0.19.5" +strum_macros = "0.19" +anyhow = { workspace = true } \ No newline at end of file diff --git a/common/Cargo.toml b/common/Cargo.toml new file mode 100644 index 0000000..552f659 --- /dev/null +++ b/common/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "common" +version = "0.1.0" +edition = "2021" + + +[dependencies] +derive_more = { workspace = true } \ No newline at end of file diff --git a/common/src/lib.rs b/common/src/lib.rs new file mode 100644 index 0000000..e69de29 diff --git a/entity/Cargo.toml b/entity/Cargo.toml new file mode 100644 index 0000000..6603cbb --- /dev/null +++ b/entity/Cargo.toml @@ -0,0 +1,57 @@ +[package] +name = "entity" +version = "0.1.0" +edition = "2021" + +[dependencies] +libpso = { workspace = true } +maps = { workspace = true } +chrono = { workspace = true } +anyhow = { workspace = true } +async-std = { workspace = true } +sqlx = { workspace = true } +thiserror = { workspace = true } +serde = { workspace = true } +async-trait = { workspace = true } +enum-utils = { workspace = true } +derive_more = { workspace = true } +refinery = { workspace = true } +lazy_static = { workspace = true } +futures = { workspace = true } +strum = { workspace = true } +strum_macros = { workspace = true } +toml = { workspace = true } + + +#libpso = { git = "http://git.sharnoth.com/jake/libpso" } +#async-std = { version = "1.9.0", features = ["unstable", "attributes"] } +#futures = "0.3.5" +#rand = "0.7.3" +#rand_chacha = "0.2.2" +#crc = "^1.0.0" +#bcrypt = "0.10" +#chrono = "0.4.11" +#serde = "*" +#serde_json = "*" +#ron = "*" +#toml = "*" +#log = "*" +#fern = { version = "0.5", features = ["colored"] } +#byteorder = "1" +#enum-utils = "0.1.2" +#derive_more = { version = "0.99.3", features = ["display"]} +#thiserror = "1.0.37" +#ages-prs = "0.1" +#async-trait = "0.1.51" +#async-recursion= "1.0.0" +#lazy_static = "1.4.0" +#barrel = { version = "0.6.5", features = ["pg"] } +#refinery = { version = "0.5.0", features = ["postgres"] } +#sqlx = { version = "0.6.2", features = ["runtime-async-std-native-tls", "postgres", "json", "chrono"] } +#strum = "0.19.5" +#strum_macros = "0.19" +#anyhow = { version = "1.0.68", features = ["backtrace"] } + +#[lib] +#name = "entity" +#path = "lib.rs" \ No newline at end of file diff --git a/src/entity/account.rs b/entity/src/account.rs similarity index 100% rename from src/entity/account.rs rename to entity/src/account.rs diff --git a/src/entity/character.rs b/entity/src/character.rs similarity index 98% rename from src/entity/character.rs rename to entity/src/character.rs index 080bb1b..643e009 100644 --- a/src/entity/character.rs +++ b/entity/src/character.rs @@ -4,8 +4,8 @@ use serde::{Serialize, Deserialize}; use libpso::packet::ship::{UpdateConfig, WriteInfoboard}; use libpso::character::settings::{DEFAULT_PALETTE_CONFIG, DEFAULT_TECH_MENU}; -use crate::entity::item::tech::Technique; -use crate::entity::account::UserAccountId; +use crate::item::tech::Technique; +use crate::account::UserAccountId; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, enum_utils::FromStr, derive_more::Display, Serialize, Deserialize, Default)] pub enum CharacterClass { diff --git a/src/entity/gateway/entitygateway.rs b/entity/src/gateway/entitygateway.rs similarity index 98% rename from src/entity/gateway/entitygateway.rs rename to entity/src/gateway/entitygateway.rs index df922ac..4f7ae67 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/entity/src/gateway/entitygateway.rs @@ -1,10 +1,10 @@ use thiserror::Error; use futures::future::{Future, BoxFuture}; -use crate::entity::account::*; -use crate::entity::character::*; -use crate::entity::item::*; -use crate::entity::room::*; +use crate::account::*; +use crate::character::*; +use crate::item::*; +use crate::room::*; // TODO: better granularity? diff --git a/src/entity/gateway/inmemory.rs b/entity/src/gateway/inmemory.rs similarity index 99% rename from src/entity/gateway/inmemory.rs rename to entity/src/gateway/inmemory.rs index 50a650e..970beed 100644 --- a/src/entity/gateway/inmemory.rs +++ b/entity/src/gateway/inmemory.rs @@ -2,11 +2,11 @@ use std::collections::BTreeMap; use std::convert::TryInto; use futures::future::{Future, BoxFuture}; -use crate::entity::account::*; -use crate::entity::character::*; -use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction, GatewayError}; -use crate::entity::item::*; -use crate::entity::room::*; +use crate::account::*; +use crate::character::*; +use crate::gateway::{EntityGateway, EntityGatewayTransaction, GatewayError}; +use crate::item::*; +use crate::room::*; use async_std::sync::{Arc, Mutex}; diff --git a/src/entity/gateway/mod.rs b/entity/src/gateway/mod.rs similarity index 100% rename from src/entity/gateway/mod.rs rename to entity/src/gateway/mod.rs diff --git a/src/entity/gateway/postgres/migrations/V0001__initial.sql b/entity/src/gateway/postgres/migrations/V0001__initial.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0001__initial.sql rename to entity/src/gateway/postgres/migrations/V0001__initial.sql diff --git a/src/entity/gateway/postgres/migrations/V0002__equips.sql b/entity/src/gateway/postgres/migrations/V0002__equips.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0002__equips.sql rename to entity/src/gateway/postgres/migrations/V0002__equips.sql diff --git a/src/entity/gateway/postgres/migrations/V0003__item_notes.sql b/entity/src/gateway/postgres/migrations/V0003__item_notes.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0003__item_notes.sql rename to entity/src/gateway/postgres/migrations/V0003__item_notes.sql diff --git a/src/entity/gateway/postgres/migrations/V0004__meseta.sql b/entity/src/gateway/postgres/migrations/V0004__meseta.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0004__meseta.sql rename to entity/src/gateway/postgres/migrations/V0004__meseta.sql diff --git a/src/entity/gateway/postgres/migrations/V0005__trade.sql b/entity/src/gateway/postgres/migrations/V0005__trade.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0005__trade.sql rename to entity/src/gateway/postgres/migrations/V0005__trade.sql diff --git a/src/entity/gateway/postgres/migrations/V0006__playtime.sql b/entity/src/gateway/postgres/migrations/V0006__playtime.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0006__playtime.sql rename to entity/src/gateway/postgres/migrations/V0006__playtime.sql diff --git a/src/entity/gateway/postgres/migrations/V0007__player_keyconfig.sql b/entity/src/gateway/postgres/migrations/V0007__player_keyconfig.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0007__player_keyconfig.sql rename to entity/src/gateway/postgres/migrations/V0007__player_keyconfig.sql diff --git a/src/entity/gateway/postgres/migrations/V0008__playtime_not_null.sql b/entity/src/gateway/postgres/migrations/V0008__playtime_not_null.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0008__playtime_not_null.sql rename to entity/src/gateway/postgres/migrations/V0008__playtime_not_null.sql diff --git a/src/entity/gateway/postgres/migrations/V0009__no_player_keyconfig.sql b/entity/src/gateway/postgres/migrations/V0009__no_player_keyconfig.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0009__no_player_keyconfig.sql rename to entity/src/gateway/postgres/migrations/V0009__no_player_keyconfig.sql diff --git a/src/entity/gateway/postgres/migrations/V0010__char_create_timestamp.sql b/entity/src/gateway/postgres/migrations/V0010__char_create_timestamp.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0010__char_create_timestamp.sql rename to entity/src/gateway/postgres/migrations/V0010__char_create_timestamp.sql diff --git a/src/entity/gateway/postgres/migrations/V0011__shared_bank.sql b/entity/src/gateway/postgres/migrations/V0011__shared_bank.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0011__shared_bank.sql rename to entity/src/gateway/postgres/migrations/V0011__shared_bank.sql diff --git a/src/entity/gateway/postgres/migrations/V0012__room.sql b/entity/src/gateway/postgres/migrations/V0012__room.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0012__room.sql rename to entity/src/gateway/postgres/migrations/V0012__room.sql diff --git a/src/entity/gateway/postgres/migrations/V0013__room2.sql b/entity/src/gateway/postgres/migrations/V0013__room2.sql similarity index 100% rename from src/entity/gateway/postgres/migrations/V0013__room2.sql rename to entity/src/gateway/postgres/migrations/V0013__room2.sql diff --git a/entity/src/gateway/postgres/migrations/mod.rs b/entity/src/gateway/postgres/migrations/mod.rs new file mode 100644 index 0000000..fd67f6f --- /dev/null +++ b/entity/src/gateway/postgres/migrations/mod.rs @@ -0,0 +1,3 @@ +use refinery::include_migration_mods; + +include_migration_mods!("src/gateway/postgres/migrations"); diff --git a/src/entity/gateway/postgres/mod.rs b/entity/src/gateway/postgres/mod.rs similarity index 100% rename from src/entity/gateway/postgres/mod.rs rename to entity/src/gateway/postgres/mod.rs diff --git a/src/entity/gateway/postgres/models.rs b/entity/src/gateway/postgres/models.rs similarity index 99% rename from src/entity/gateway/postgres/models.rs rename to entity/src/gateway/postgres/models.rs index f3a2f39..13c2a6b 100644 --- a/src/entity/gateway/postgres/models.rs +++ b/entity/src/gateway/postgres/models.rs @@ -4,13 +4,13 @@ use std::convert::Into; use serde::{Serialize, Deserialize}; use libpso::character::settings; use libpso::util::vec_to_array; -use crate::entity::account::*; -use crate::entity::character::*; -use crate::entity::item::*; -use crate::entity::room::*; -use crate::ship::map::MapArea; -use crate::ship::room::{Episode, Difficulty}; -use crate::ship::monster::MonsterType; +use crate::account::*; +use crate::character::*; +use crate::item::*; +use crate::room::*; +use maps::area::MapArea; +use maps::room::{Episode, Difficulty}; +use maps::monster::MonsterType; #[derive(Debug, sqlx::FromRow)] pub struct PgUserAccount { diff --git a/src/entity/gateway/postgres/postgres.rs b/entity/src/gateway/postgres/postgres.rs similarity index 99% rename from src/entity/gateway/postgres/postgres.rs rename to entity/src/gateway/postgres/postgres.rs index c31217f..f1219ba 100644 --- a/src/entity/gateway/postgres/postgres.rs +++ b/entity/src/gateway/postgres/postgres.rs @@ -1,16 +1,16 @@ // this lint is currently bugged and suggests incorrect code https://github.com/rust-lang/rust-clippy/issues/9123 #![allow(clippy::explicit_auto_deref)] -use std::convert::{From, TryFrom, Into}; +use std::convert::{From, Into}; use futures::future::{Future, BoxFuture}; use futures::stream::{StreamExt, FuturesOrdered}; use async_std::sync::{Arc, Mutex}; use libpso::character::guildcard; -use crate::entity::account::*; -use crate::entity::character::*; -use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction, GatewayError}; -use crate::entity::item::*; -use crate::entity::room::*; +use crate::account::*; +use crate::character::*; +use crate::gateway::{EntityGateway, EntityGatewayTransaction, GatewayError}; +use crate::item::*; +use crate::room::*; use super::models::*; use sqlx::postgres::PgPoolOptions; @@ -19,7 +19,7 @@ use sqlx::Connection; mod embedded { use refinery::embed_migrations; - embed_migrations!("src/entity/gateway/postgres/migrations"); + embed_migrations!("src/gateway/postgres/migrations"); } diff --git a/src/entity/item/armor.rs b/entity/src/item/armor.rs similarity index 99% rename from src/entity/item/armor.rs rename to entity/src/item/armor.rs index 45e9ed4..bd0cc48 100644 --- a/src/entity/item/armor.rs +++ b/entity/src/item/armor.rs @@ -1,5 +1,5 @@ use serde::{Serialize, Deserialize}; -use crate::entity::item::ItemEntityId; +use crate::item::ItemEntityId; #[derive(Debug, Copy, Clone)] pub enum ItemParseError { diff --git a/src/entity/item/esweapon.rs b/entity/src/item/esweapon.rs similarity index 100% rename from src/entity/item/esweapon.rs rename to entity/src/item/esweapon.rs diff --git a/src/entity/item/mag.rs b/entity/src/item/mag.rs similarity index 99% rename from src/entity/item/mag.rs rename to entity/src/item/mag.rs index 17fa1b4..45d424a 100644 --- a/src/entity/item/mag.rs +++ b/entity/src/item/mag.rs @@ -1,9 +1,9 @@ -use thiserror::Error; use std::collections::HashMap; +use thiserror::Error; use serde::{Serialize, Deserialize}; -use crate::entity::item::tool::ToolType; -use crate::entity::character::{CharacterClass, SectionID}; -use crate::entity::item::ItemEntityId; +use crate::item::tool::ToolType; +use crate::character::{CharacterClass, SectionID}; +use crate::item::ItemEntityId; use std::io::Read; use std::cmp::Ordering::{Less, Greater, Equal}; diff --git a/src/entity/item/mod.rs b/entity/src/item/mod.rs similarity index 84% rename from src/entity/item/mod.rs rename to entity/src/item/mod.rs index 7023f7c..d418579 100644 --- a/src/entity/item/mod.rs +++ b/entity/src/item/mod.rs @@ -9,11 +9,11 @@ pub mod mag; pub mod esweapon; use serde::{Serialize, Deserialize}; -use crate::entity::character::CharacterEntityId; -use crate::entity::room::RoomEntityId; -use crate::ship::map::MapArea; -use crate::ship::monster::MonsterType; -use crate::ship::drops::ItemDropType; +use crate::character::CharacterEntityId; +use crate::room::RoomEntityId; +use maps::area::MapArea; +use maps::monster::MonsterType; +//use crate::ship::drops::ItemDropType; #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)] pub struct ItemEntityId(pub u32); @@ -156,26 +156,6 @@ impl ItemDetail { } } - pub fn parse_item_from_bytes(data: [u8; 16]) -> Option { - let item_type = weapon::WeaponType::parse_type([data[0],data[1],data[2]]).map(ItemType::Weapon) - .or_else(|_| armor::ArmorType::parse_type([data[0],data[1],data[2]]).map(ItemType::Armor)) - .or_else(|_| shield::ShieldType::parse_type([data[0],data[1],data[2]]).map(ItemType::Shield)) - .or_else(|_| unit::UnitType::parse_type([data[0],data[1],data[2]]).map(ItemType::Unit)) - .or_else(|_| mag::MagType::parse_type([data[0],data[1],data[2]]).map(ItemType::Mag)) - .or_else(|_| tool::ToolType::parse_type([data[0],data[1],data[2]]).map(ItemType::Tool)) - .or_else(|_| esweapon::ESWeaponType::parse_type([data[0],data[1],data[2]]).map(ItemType::ESWeapon)).ok()?; - - match item_type { - ItemType::Weapon(_w) => Some(ItemDropType::Weapon(weapon::Weapon::from_bytes(data).ok()?)), - ItemType::Armor(_a) => Some(ItemDropType::Armor(armor::Armor::from_bytes(data).ok()?)), - ItemType::Shield(_s) => Some(ItemDropType::Shield(shield::Shield::from_bytes(data).ok()?)), - ItemType::Unit(_u) => Some(ItemDropType::Unit(unit::Unit::from_bytes(data).ok()?)), - ItemType::Mag(_m) => Some(ItemDropType::Mag(mag::Mag::from_bytes(data).ok()?)), - ItemType::Tool(_t) => Some(ItemDropType::Tool(tool::Tool::from_bytes(data).ok()?)), - _ => None, - } - } - pub fn as_client_bytes(&self) -> [u8; 16] { match self { ItemDetail::Weapon(w) => w.as_bytes(), diff --git a/src/entity/item/shield.rs b/entity/src/item/shield.rs similarity index 100% rename from src/entity/item/shield.rs rename to entity/src/item/shield.rs diff --git a/src/entity/item/tech.rs b/entity/src/item/tech.rs similarity index 100% rename from src/entity/item/tech.rs rename to entity/src/item/tech.rs diff --git a/src/entity/item/tool.rs b/entity/src/item/tool.rs similarity index 100% rename from src/entity/item/tool.rs rename to entity/src/item/tool.rs diff --git a/src/entity/item/unit.rs b/entity/src/item/unit.rs similarity index 100% rename from src/entity/item/unit.rs rename to entity/src/item/unit.rs diff --git a/src/entity/item/weapon.rs b/entity/src/item/weapon.rs similarity index 99% rename from src/entity/item/weapon.rs rename to entity/src/item/weapon.rs index 29a9357..a5753d6 100644 --- a/src/entity/item/weapon.rs +++ b/entity/src/item/weapon.rs @@ -1,4 +1,4 @@ -use crate::entity::item::ItemEntityId; +use crate::item::ItemEntityId; use serde::{Serialize, Deserialize}; #[derive(Debug, Copy, Clone)] diff --git a/src/entity/mod.rs b/entity/src/lib.rs similarity index 100% rename from src/entity/mod.rs rename to entity/src/lib.rs diff --git a/src/entity/room.rs b/entity/src/room.rs similarity index 93% rename from src/entity/room.rs rename to entity/src/room.rs index a5eeea4..30d3b6b 100644 --- a/src/entity/room.rs +++ b/entity/src/room.rs @@ -1,8 +1,8 @@ use serde::{Serialize, Deserialize}; -use crate::entity::character::{CharacterEntityId, SectionID}; -use crate::ship::room::{Episode, Difficulty}; +use crate::character::{CharacterEntityId, SectionID}; +use maps::room::{Episode, Difficulty}; #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)] diff --git a/entity/src/team.rs b/entity/src/team.rs new file mode 100644 index 0000000..2a5bfac --- /dev/null +++ b/entity/src/team.rs @@ -0,0 +1,31 @@ +use serde::{Serialize, Deserialize}; + +use super::account::UserAccountId; + +// [2022-10-23 00:11:18][elseware::common::mainloop::client][WARN] error RecvServerPacket::from_bytes: WrongPacketForServerType(490, [40, 0, 234, 1, 0, 0, 0, 0, 9, 0, 74, 0, 97, 0, 115, 0, 100, 0, 102, 0, 0, 0, 0, 0, 192, 52, 67, 3, 60, 159, 129, 0, 32, 64, 233, 10, 196, 156, 152, 0]) +// [2022-10-23 00:20:14][elseware::common::mainloop::client][WARN] error RecvServerPacket::from_bytes: WrongPacketForServerType(490, [40, 0, 234, 1, 0, 0, 0, 0, 9, 0, 74, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 0, 0, 152, 0]) + + +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)] +pub struct TeamEntityId(pub u32); + +pub struct NewTeamEntity { + pub created_by: UserAccountId, + pub name: String, +} + + +#[derive(Debug, Clone)] +pub struct TeamEntity { + pub id: TeamEntityId, + pub owner: UserAccountId, + pub name: String, + + pub team_flag: [u8; 2048], +} + + + + + + diff --git a/maps/Cargo.toml b/maps/Cargo.toml new file mode 100644 index 0000000..cf0401e --- /dev/null +++ b/maps/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "maps" +version = "0.1.0" +edition = "2021" + +[dependencies] +common = { workspace = true } +byteorder = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } +rand = { workspace = true } +rand_chacha = { workspace = true } +toml = { workspace = true } +enum-utils = { workspace = true } +derive_more = { workspace = true } diff --git a/src/ship/map/area.rs b/maps/src/area.rs similarity index 99% rename from src/ship/map/area.rs rename to maps/src/area.rs index 02361c3..bb64737 100644 --- a/src/ship/map/area.rs +++ b/maps/src/area.rs @@ -2,7 +2,7 @@ use serde::{Serialize, Deserialize}; use std::collections::HashMap; use thiserror::Error; -use crate::ship::room::Episode; +use crate::room::Episode; use std::fmt; #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] diff --git a/src/ship/map/enemy.rs b/maps/src/enemy.rs similarity index 93% rename from src/ship/map/enemy.rs rename to maps/src/enemy.rs index 4989041..08e0f61 100644 --- a/src/ship/map/enemy.rs +++ b/maps/src/enemy.rs @@ -1,19 +1,24 @@ // TOOD: `pub(super) for most of these?` use std::io::{Read}; use std::collections::HashMap; +use std::fs::File; +use std::path::PathBuf; use byteorder::{LittleEndian, ReadBytesExt}; use thiserror::Error; - -use crate::ship::ship::ShipEvent; -use crate::ship::monster::MonsterType; -use crate::ship::room::Episode; - -use crate::ship::map::*; - use rand::{Rng, SeedableRng}; use serde::{Serialize, Deserialize}; -use crate::ship::drops::{load_rare_monster_file}; + +use crate::area::{MapArea, MapAreaError}; +use crate::room::Episode; +use crate::monster::MonsterType; + +#[derive(Clone, Copy)] +pub enum RareEnemyEvent { + Easter, + Halloween, + Christmas, +} #[derive(Debug, Copy, Clone)] pub struct RawMapEnemy { @@ -69,6 +74,17 @@ impl RawMapEnemy { } +pub fn load_rare_monster_file(episode: Episode) -> T { + // TODO: where does the rare monster toml file actually live + let mut path = PathBuf::from("data/battle_param/"); + path.push(episode.to_string().to_lowercase() + "_rare_monster.toml"); + + let mut f = File::open(path).unwrap(); + let mut s = String::new(); + f.read_to_string(&mut s); + toml::from_str::(s.as_str()).unwrap() +} + #[derive(Error, Debug)] #[error("")] pub enum MapEnemyError { @@ -76,6 +92,7 @@ pub enum MapEnemyError { MapAreaError(#[from] MapAreaError), } + // making this `pub type` doesn't allow `impl`s to be defined? #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RareMonsterAppearTable { @@ -103,7 +120,7 @@ impl RareMonsterAppearTable { rand_chacha::ChaChaRng::from_entropy().gen::() < *self.appear_rate.get(monster).unwrap_or(&0.0f32) } - pub fn apply(&self, enemy: MapEnemy, event: ShipEvent) -> MapEnemy { + pub fn apply(&self, enemy: MapEnemy, event: Option) -> MapEnemy { if enemy.can_be_rare() && self.roll_is_rare(&enemy.monster) { enemy.into_rare(event) } @@ -345,12 +362,12 @@ impl MapEnemy { guaranteed rare monsters don't count towards the limit */ #[must_use] - pub fn into_rare(self, event: ShipEvent) -> MapEnemy { + pub fn into_rare(self, event: Option) -> MapEnemy { match (self.monster, self.map_area.to_episode(), event) { (MonsterType::RagRappy, Episode::One, _) => {MapEnemy {monster: MonsterType::AlRappy, shiny:true, ..self}}, - (MonsterType::RagRappy, Episode::Two, ShipEvent::Easter) => {MapEnemy {monster: MonsterType::EasterRappy, shiny:true, ..self}}, - (MonsterType::RagRappy, Episode::Two, ShipEvent::Halloween) => {MapEnemy {monster: MonsterType::HalloRappy, shiny:true, ..self}}, - (MonsterType::RagRappy, Episode::Two, ShipEvent::Christmas) => {MapEnemy {monster: MonsterType::StRappy, shiny:true, ..self}}, + (MonsterType::RagRappy, Episode::Two, Some(RareEnemyEvent::Easter)) => {MapEnemy {monster: MonsterType::EasterRappy, shiny:true, ..self}}, + (MonsterType::RagRappy, Episode::Two, Some(RareEnemyEvent::Halloween)) => {MapEnemy {monster: MonsterType::HalloRappy, shiny:true, ..self}}, + (MonsterType::RagRappy, Episode::Two, Some(RareEnemyEvent::Christmas)) => {MapEnemy {monster: MonsterType::StRappy, shiny:true, ..self}}, (MonsterType::RagRappy, Episode::Two, _) => {MapEnemy {monster: MonsterType::LoveRappy, shiny:true, ..self}}, (MonsterType::Hildebear, _, _) => {MapEnemy {monster: MonsterType::Hildeblue, shiny:true, ..self}}, (MonsterType::PoisonLily, _, _) => {MapEnemy {monster: MonsterType::NarLily, shiny:true, ..self}}, diff --git a/maps/src/lib.rs b/maps/src/lib.rs new file mode 100644 index 0000000..fa2b60e --- /dev/null +++ b/maps/src/lib.rs @@ -0,0 +1,7 @@ +pub mod area; +pub mod enemy; +pub mod object; +pub mod variant; +pub mod maps; +pub mod monster; +pub mod room; diff --git a/src/ship/map/maps.rs b/maps/src/maps.rs similarity index 97% rename from src/ship/map/maps.rs rename to maps/src/maps.rs index 05c7e29..6684d52 100644 --- a/src/ship/map/maps.rs +++ b/maps/src/maps.rs @@ -6,14 +6,14 @@ use std::fs::File; use thiserror::Error; -use crate::ship::ship::ShipEvent; -use crate::ship::monster::MonsterType; -use crate::ship::room::{Episode, RoomMode, PlayerMode}; - -// TODO: don't use * -use crate::ship::map::*; - +//use crate::ship::ship::ShipEvent; +use crate::area::MapArea; +use crate::enemy::{MapEnemy, RawMapEnemy, RareEnemyEvent, RareMonsterAppearTable}; +use crate::monster::MonsterType; +use crate::variant::{MapVariant, MapVariantMode}; +use crate::object::{MapObject, RawMapObject}; +use crate::room::{Episode, RoomMode, PlayerMode}; pub fn objects_from_stream(cursor: &mut impl Read, episode: &Episode, map_area: &MapArea) -> Vec> { let mut object_data = Vec::new(); @@ -325,7 +325,7 @@ impl Maps { enemies: Vec>, objects: Vec>, rare_monster_table: &RareMonsterAppearTable, - event: ShipEvent) + event: Option) { self.enemy_data = enemies .into_iter() @@ -358,7 +358,7 @@ impl Maps { } } -pub fn generate_free_roam_maps(room_mode: RoomMode, event: ShipEvent) -> Maps { +pub fn generate_free_roam_maps(room_mode: RoomMode, event: Option) -> Maps { let rare_monster_table = RareMonsterAppearTable::new(room_mode.episode()); let map_variants = default_map_variants(room_mode.episode(), room_mode.player_mode()); Maps { diff --git a/maps/src/monster.rs b/maps/src/monster.rs new file mode 100644 index 0000000..a72288d --- /dev/null +++ b/maps/src/monster.rs @@ -0,0 +1,212 @@ +#![allow(dead_code)] +use std::collections::HashMap; +use std::fs::File; +use std::io::Read; +use std::path::PathBuf; +use serde::{Serialize, Deserialize}; +use crate::room::{Difficulty, Episode, RoomMode}; + + +#[derive(Debug)] +pub enum MonsterParseError { + UnknownMonster(String), +} + +pub struct MonsterStatError; + +#[derive(Debug, Serialize, Deserialize, Copy, Clone, Hash, Eq, PartialEq, enum_utils::FromStr, derive_more::Display)] +pub enum MonsterType { + Hildebear, + Hildeblue, + Mothmant, + Monest, + RagRappy, + AlRappy, + SavageWolf, + BarbarousWolf, + Booma, + Gobooma, + Gigobooma, + GrassAssassin, + PoisonLily, + NarLily, + NanoDragon, + EvilShark, + PalShark, + GuilShark, + PofuillySlime, + PouillySlime, + PanArms, + Hidoom, + Migium, + Dubchic, + Garanz, + SinowBeat, + SinowGold, + Canadine, + Canane, + RingCanadine, + Delsaber, + ChaosSorcerer, + BeeR, + BeeL, + DarkGunner, + DeathGunner, + ChaosBringer, + DarkBelra, + Claw, + Bulk, + Bulclaw, + Dimenian, + LaDimenian, + SoDimenian, + Dragon, + DeRolLe, + DeRolLeBody, + DeRolLeMine, + VolOptPartA, + VolOptPillar, + VolOptMonitor, + VolOptAmp, + VolOptCore, + VolOptUnused, + VolOpt, + VolOptTrap, + DarkFalz, + DarkFalz1, + DarkFalz2, + DarkFalz3, + Darvant, + UltDarvant, + Dubwitch, + Gillchic, + EventRappy, + Merillia, + Meriltas, + Gee, + GiGue, + Mericarol, + Merikle, + Mericus, + UlGibbon, + ZolGibbon, + Gibbles, + SinowBerill, + SinowSpigell, + Dolmolm, + Dolmdarl, + Morfos, + Recobox, + Recon, + SinowZoa, + SinowZele, + Deldepth, + Delbiter, + BarbaRay, + PigRay, + GolDragon, + GalGryphon, + OlgaFlow, + OlgaFlow1, + OlgaFlow2, + Gael, + Giel, + StRappy, + HalloRappy, + EasterRappy, + LoveRappy, + IllGill, + DelLily, + Epsilon, + Epsiguard, + Boota, + ZeBoota, + BaBoota, + SandRappyCrater, + SandRappyDesert, + ZuCrater, + PazuzuCrater, + Astark, + SatelliteLizardCrater, + YowieCrater, + Dorphon, + DorphonEclair, + Goran, + GoranDetonator, + PyroGoran, + DelRappyCrater, + DelRappyDesert, + MerissaA, + MerissaAA, + ZuDesert, + PazuzuDesert, + SatelliteLizardDesert, + YowieDesert, + Girtablulu, + SaintMillion, + Shambertin, + Kondrieu, +} + + +#[derive(Deserialize, Debug)] +pub struct MonsterStats { + pub atp: u16, + pub mst: u16, + pub evp: u16, + pub hp: u16, + pub dfp: u16, + pub ata: u16, + pub lck: u16, + pub esp: u16, + pub exp: u32, +} + +fn load_battle_param(filename: &str) -> HashMap { + let mut path = PathBuf::from("data/battle_param/"); + path.push(filename); + + let mut f = File::open(path).unwrap(); + let mut s = String::new(); + f.read_to_string(&mut s).unwrap(); + toml::from_str::>(s.as_str()).unwrap() + .into_iter() + .map(|(monster_name, stats)| { + (monster_name.parse().unwrap(), stats) + }).collect() +} + +pub fn load_monster_stats_table(mode: &RoomMode) -> Result, MonsterStatError> { + match mode { + RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep1_multi_normal.toml")), + RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep1_multi_hard.toml")), + RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep1_multi_veryhard.toml")), + RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep1_multi_ultimate.toml")), + + RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep2_multi_normal.toml")), + RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep2_multi_hard.toml")), + RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep2_multi_veryhard.toml")), + RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep2_multi_ultimate.toml")), + + RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep4_multi_normal.toml")), + RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep4_multi_hard.toml")), + RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep4_multi_veryhard.toml")), + RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep4_multi_ultimate.toml")), + + RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep1_solo_normal.toml")), + RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep1_solo_hard.toml")), + RoomMode::Single {episode: Episode::One, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep1_solo_veryhard.toml")), + RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep1_solo_ultimate.toml")), + + RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep2_solo_normal.toml")), + RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep2_solo_hard.toml")), + RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep2_solo_veryhard.toml")), + RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep2_solo_ultimate.toml")), + + RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep4_solo_normal.toml")), + RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep4_solo_hard.toml")), + RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep4_solo_veryhard.toml")), + RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep4_solo_ultimate.toml")), + _ => Err(MonsterStatError), + } +} diff --git a/src/ship/map/object.rs b/maps/src/object.rs similarity index 98% rename from src/ship/map/object.rs rename to maps/src/object.rs index 81bce6a..0f73442 100644 --- a/src/ship/map/object.rs +++ b/maps/src/object.rs @@ -1,13 +1,11 @@ // TOOD: `pub(super) for most of these?` -use std::io::{Read}; +use std::io::Read; use byteorder::{LittleEndian, ReadBytesExt}; -use crate::ship::room::Episode; - -// TODO: don't use * -use crate::ship::map::*; +use crate::room::Episode; +use crate::area::MapArea; #[derive(Debug, Copy, Clone)] diff --git a/maps/src/room.rs b/maps/src/room.rs new file mode 100644 index 0000000..8370e7c --- /dev/null +++ b/maps/src/room.rs @@ -0,0 +1,150 @@ +#[derive(Debug, Copy, Clone, derive_more::Display)] +pub enum Episode { + #[display(fmt="ep1")] + One, + #[display(fmt="ep2")] + Two, + #[display(fmt="ep4")] + Four, +} + +impl TryFrom for Episode { + type Error = (); + + fn try_from(value: u8) -> Result { + match value { + 1 => Ok(Episode::One), + 2 => Ok(Episode::Two), + 3 => Ok(Episode::Four), + _ => Err(()) + } + } +} + +impl From for u8 { + fn from(other: Episode) -> u8 { + match other { + Episode::One => 1, + Episode::Two => 2, + Episode::Four => 3, + } + } +} + +impl Episode { + pub fn from_quest(value: u8) -> Option { + match value { + 0 => Some(Episode::One), + 1 => Some(Episode::Two), + 2 => Some(Episode::Four), + _ => None, + } + } +} + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, derive_more::Display)] +pub enum Difficulty { + Normal, + Hard, + VeryHard, + Ultimate, +} + +impl TryFrom for Difficulty { + type Error = (); + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(Difficulty::Normal), + 1 => Ok(Difficulty::Hard), + 2 => Ok(Difficulty::VeryHard), + 3 => Ok(Difficulty::Ultimate), + _ => Err(()) + } + } +} + +impl From for u8 { + fn from(other: Difficulty) -> u8 { + match other { + Difficulty::Normal => 0, + Difficulty::Hard => 1, + Difficulty::VeryHard => 2, + Difficulty::Ultimate => 3, + } + } +} + +#[derive(Debug, Copy, Clone)] +pub enum PlayerMode { + Single, + Multi, +} + +impl PlayerMode { + pub fn value(&self) -> u8 { + match self { + PlayerMode::Single => 1, + PlayerMode::Multi => 0, + } + } +} + +#[derive(Debug, Copy, Clone, derive_more::Display)] +pub enum RoomMode { + #[display(fmt="single")] + Single { + episode: Episode, + difficulty: Difficulty, + }, + #[display(fmt="multi")] + Multi { + episode: Episode, + difficulty: Difficulty, + }, + #[display(fmt="challenge")] + Challenge { + episode: Episode, + }, + #[display(fmt="battle")] + Battle { + episode: Episode, + difficulty: Difficulty, + } +} + + +impl RoomMode { + pub fn difficulty(&self) -> Difficulty { + match self { + RoomMode::Single {difficulty, ..} => *difficulty, + RoomMode::Multi {difficulty, ..} => *difficulty, + RoomMode::Battle {difficulty, ..} => *difficulty, + RoomMode::Challenge {..} => Difficulty::Normal, + } + } + + pub fn episode(&self) -> Episode { + match self { + RoomMode::Single {episode, ..} => *episode, + RoomMode::Multi {episode, ..} => *episode, + RoomMode::Battle {episode, ..} => *episode, + RoomMode::Challenge {episode, ..} => *episode, + } + } + + pub fn battle(&self) -> bool { + matches!(self, RoomMode::Battle {..}) + } + + pub fn challenge(&self) -> bool { + matches!(self, RoomMode::Challenge {..}) + } + + pub fn player_mode(&self) -> PlayerMode { + match self { + RoomMode::Single {..} => PlayerMode::Single, + _ => PlayerMode::Multi, + } + } +} diff --git a/src/ship/map/variant.rs b/maps/src/variant.rs similarity index 99% rename from src/ship/map/variant.rs rename to maps/src/variant.rs index 0fa7c65..78fa4bf 100644 --- a/src/ship/map/variant.rs +++ b/maps/src/variant.rs @@ -3,7 +3,8 @@ use rand::Rng; // TODO: don't use * -use crate::ship::map::*; +//use crate::map::*; +use crate::area::MapArea; #[derive(Debug, PartialEq, Eq)] pub enum MapVariantMode { diff --git a/networking/Cargo.toml b/networking/Cargo.toml new file mode 100644 index 0000000..b0ee8a2 --- /dev/null +++ b/networking/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "networking" +version = "0.1.0" +edition = "2021" diff --git a/networking/src/lib.rs b/networking/src/lib.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/bin/login.rs b/src/bin/login.rs index f8b6b94..28d78f0 100644 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -1,5 +1,5 @@ use log::{info}; -use elseware::entity::gateway::postgres::PostgresGateway; +use entity::gateway::postgres::PostgresGateway; use elseware::login::login::LoginServerState; use elseware::login::character::CharacterServerState; use elseware::common::interserver::AuthToken; diff --git a/src/bin/main.rs b/src/bin/main.rs index 0a3ada0..23aa720 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -8,11 +8,11 @@ use elseware::patch::patch::{PatchServerState, generate_patch_tree, load_config, use elseware::ship::ship::{ShipServerStateBuilder, ShipEvent}; #[allow(unused_imports)] -use elseware::entity::gateway::{EntityGateway, InMemoryGateway, PostgresGateway}; -use elseware::entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; -use elseware::entity::character::NewCharacterEntity; -use elseware::entity::item::{NewItemEntity, ItemDetail, InventoryItemEntity}; -use elseware::entity::item; +use entity::gateway::{EntityGateway, InMemoryGateway, PostgresGateway}; +use entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; +use entity::character::NewCharacterEntity; +use entity::item::{NewItemEntity, ItemDetail, InventoryItemEntity}; +use entity::item; fn setup_logger() { let colors = fern::colors::ColoredLevelConfig::new() diff --git a/src/bin/ship.rs b/src/bin/ship.rs index ff1ccc6..0f289b7 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -1,5 +1,5 @@ use log::{info}; -use elseware::entity::gateway::postgres::PostgresGateway; +use entity::gateway::postgres::PostgresGateway; use elseware::ship::ship::ShipServerStateBuilder; use elseware::common::interserver::AuthToken; diff --git a/src/common/interserver.rs b/src/common/interserver.rs index 1f6e0ff..be49a9f 100644 --- a/src/common/interserver.rs +++ b/src/common/interserver.rs @@ -2,8 +2,8 @@ use std::net::Ipv4Addr; use async_std::channel; use serde::{Serialize, Deserialize}; use serde::de::DeserializeOwned; -use crate::entity::account::UserAccountId; -use crate::entity::character::CharacterEntityId; +use entity::account::UserAccountId; +use entity::character::CharacterEntityId; #[derive(Debug, Copy, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct ServerId(pub usize); diff --git a/src/common/leveltable.rs b/src/common/leveltable.rs index 9fb1465..7b06966 100644 --- a/src/common/leveltable.rs +++ b/src/common/leveltable.rs @@ -1,6 +1,6 @@ use std::fs::File; use serde_json::Value; -use crate::entity::character::CharacterClass; +use entity::character::CharacterClass; use std::sync::LazyLock; pub static LEVEL_TABLE: LazyLock = LazyLock::new(CharacterLevelTable::default); diff --git a/src/common/mainloop/interserver.rs b/src/common/mainloop/interserver.rs index dbe940d..d524952 100644 --- a/src/common/mainloop/interserver.rs +++ b/src/common/mainloop/interserver.rs @@ -13,8 +13,7 @@ use crate::common::interserver::{ServerId, InterserverActor}; use libpso::crypto::{PSOCipher, NullCipher, CipherError}; use crate::common::serverstate::{ServerState, SendServerPacket, RecvServerPacket}; use crate::login::character::CharacterServerState; -//use crate::ship::ship::ShipServerState; -use crate::entity::gateway::entitygateway::EntityGateway; +use entity::gateway::entitygateway::EntityGateway; use async_std::channel; use std::fmt::Debug; diff --git a/src/entity/gateway/postgres/migrations/mod.rs b/src/entity/gateway/postgres/migrations/mod.rs deleted file mode 100644 index 533298a..0000000 --- a/src/entity/gateway/postgres/migrations/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -use refinery::include_migration_mods; - -include_migration_mods!("src/entity/gateway/postgres/migrations"); diff --git a/src/lib.rs b/src/lib.rs index 54fc603..3802b3c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,7 @@ extern crate test; pub mod common; -pub mod entity; +//pub mod entity; pub mod patch; pub mod login; pub mod ship; diff --git a/src/login/character.rs b/src/login/character.rs index f23beea..07969ef 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -12,8 +12,8 @@ use libpso::packet::login::*; use libpso::packet::ship::{MenuDetail, SmallLeftDialog}; use libpso::{PacketParseError, PSOPacket}; use libpso::crypto::bb::PSOBBCipher; -use crate::entity::item; use libpso::character::character; +use entity::item; use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; @@ -21,15 +21,15 @@ use crate::common::interserver::{ServerId, InterserverActor, LoginMessage, ShipM use crate::common::leveltable::LEVEL_TABLE; use libpso::{utf8_to_array, utf8_to_utf16_array}; -use crate::entity::gateway::{EntityGateway, GatewayError}; -use crate::entity::account::{UserAccountId, UserAccountEntity, NewUserSettingsEntity, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; -use crate::entity::item::{NewItemEntity, ItemDetail, ItemNote, InventoryItemEntity, InventoryEntity, BankEntity, BankIdentifier, EquippedEntity, Meseta}; -use crate::entity::item::weapon::Weapon; -use crate::entity::item::armor::Armor; -use crate::entity::item::tech::Technique; -use crate::entity::item::tool::Tool; -use crate::entity::item::mag::Mag; -use crate::entity::character::{CharacterEntity, NewCharacterEntity, CharacterClass, TechLevel}; +use entity::gateway::{EntityGateway, GatewayError}; +use entity::account::{UserAccountId, UserAccountEntity, NewUserSettingsEntity, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; +use entity::item::{NewItemEntity, ItemDetail, ItemNote, InventoryItemEntity, InventoryEntity, BankEntity, BankIdentifier, EquippedEntity, Meseta}; +use entity::item::weapon::Weapon; +use entity::item::armor::Armor; +use entity::item::tech::Technique; +use entity::item::tool::Tool; +use entity::item::mag::Mag; +use entity::character::{CharacterEntity, NewCharacterEntity, CharacterClass, TechLevel}; use crate::login::login::{get_login_status}; use crate::common::interserver::AuthToken; @@ -484,7 +484,7 @@ impl CharacterServerState { async fn set_flag(&mut self, id: ClientId, setflag: &SetFlag) -> Result, anyhow::Error> { let mut client = self.clients.write().await; let client = client.get_mut(&id).ok_or_else(|| CharacterError::ClientNotFound(id))?; - let mut user = client.user.as_mut().unwrap(); + let user = client.user.as_mut().unwrap(); user.flags = setflag.flags; self.entity_gateway.save_user(user).await.unwrap(); Ok(None.into_iter()) @@ -515,7 +515,7 @@ impl CharacterServerState { async fn character_preview(&mut self, id: ClientId, preview: &CharacterPreview) -> Result, anyhow::Error> { let mut client = self.clients.write().await; let client = client.get_mut(&id).ok_or_else(|| CharacterError::ClientNotFound(id))?; - let mut user = client.user.as_mut().unwrap(); + let user = client.user.as_mut().unwrap(); if user.flags == USERFLAG_NEWCHAR { new_character(&mut self.entity_gateway, user, preview).await? } @@ -834,9 +834,21 @@ impl<'a> SelectScreenCharacterBuilder<'a> { #[cfg(test)] mod test { use super::*; - use crate::entity::account::*; + use entity::account::*; use libpso::character::{settings, character}; - use crate::entity::gateway::{InMemoryGateway, GatewayError}; + use entity::gateway::{InMemoryGateway, EntityGatewayTransaction, GatewayError}; + + #[derive(Clone)] + struct CharTestDb; + + impl EntityGateway for CharTestDb { + type Transaction<'t> = CharTestDb where Self: 't; + } + + impl EntityGatewayTransaction for CharTestDb { + type ParentGateway = CharTestDb; + } + #[async_std::test] async fn test_option_send() { @@ -846,7 +858,7 @@ mod test { #[async_trait::async_trait] impl EntityGateway for TestData { - type Transaction<'a> = () where Self: 'a; + type Transaction<'a> = CharTestDb where Self: 'a; async fn get_user_settings_by_user(&mut self, user: &UserAccountEntity) -> Result { Ok(UserSettingsEntity { id: UserSettingsId(0), @@ -889,7 +901,7 @@ mod test { #[derive(Clone)] struct TestData; impl EntityGateway for TestData { - type Transaction<'a> = () where Self: 'a; + type Transaction<'a> = CharTestDb where Self: 'a; } let mut server = CharacterServerState::new(TestData {}, AuthToken("".into())); let send = server.handle(ClientId(1), RecvCharacterPacket::Checksum(Checksum {checksum: 1234, diff --git a/src/login/login.rs b/src/login/login.rs index b4fcad6..4b1433c 100644 --- a/src/login/login.rs +++ b/src/login/login.rs @@ -14,8 +14,8 @@ use libpso::util::array_to_utf8; use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; -use crate::entity::gateway::EntityGateway; -use crate::entity::account::{UserAccountEntity}; +use entity::gateway::EntityGateway; +use entity::account::{UserAccountEntity}; pub const LOGIN_PORT: u16 = 12000; pub const COMMUNICATION_PORT: u16 = 12123; @@ -178,8 +178,8 @@ impl ServerState for LoginServerState { #[cfg(test)] mod test { use super::*; - use crate::entity::account::{UserAccountId}; - use crate::entity::gateway::{EntityGatewayTransaction, GatewayError}; + use entity::account::{UserAccountId}; + use entity::gateway::{EntityGatewayTransaction, GatewayError}; const LOGIN_PACKET: RecvLoginPacket = RecvLoginPacket::Login(Login { tag: 65536, @@ -204,13 +204,16 @@ mod test { character_slot: 0, } }); - - impl EntityGateway for () { - type Transaction<'t> = () where Self: 't; + + #[derive(Clone)] + struct LoginTestDb; + + impl EntityGateway for LoginTestDb { + type Transaction<'t> = LoginTestDb where Self: 't; } - impl EntityGatewayTransaction for () { - type ParentGateway = (); + impl EntityGatewayTransaction for LoginTestDb { + type ParentGateway = LoginTestDb; } #[async_std::test] @@ -221,7 +224,7 @@ mod test { #[async_trait::async_trait] impl EntityGateway for TestData { - type Transaction<'t> = () where Self: 't; + type Transaction<'t> = LoginTestDb where Self: 't; async fn get_user_by_name(&mut self, name: String) -> Result { assert!(name == "testuser"); Ok(UserAccountEntity { @@ -280,7 +283,7 @@ mod test { #[async_trait::async_trait] impl EntityGateway for TestData { - type Transaction<'t> = () where Self: 't; + type Transaction<'t> = LoginTestDb where Self: 't; async fn get_user_by_name(&mut self, _name: String) -> Result { Err(GatewayError::Error) } @@ -315,7 +318,7 @@ mod test { #[async_trait::async_trait] impl EntityGateway for TestData { - type Transaction<'t> = () where Self: 't; + type Transaction<'t> = LoginTestDb where Self: 't; async fn get_user_by_name(&mut self, name: String) -> Result { assert!(name == "testuser"); Ok(UserAccountEntity { @@ -365,7 +368,7 @@ mod test { #[async_trait::async_trait] impl EntityGateway for TestData { - type Transaction<'t> = () where Self: 't; + type Transaction<'t> = LoginTestDb where Self: 't; async fn get_user_by_name(&mut self, name: String) -> Result { assert!(name == "testuser"); Ok(UserAccountEntity { diff --git a/src/ship/character.rs b/src/ship/character.rs index 348f8ac..afe73c6 100644 --- a/src/ship/character.rs +++ b/src/ship/character.rs @@ -1,10 +1,10 @@ use libpso::character::character; use crate::common::leveltable::CharacterStats; -use crate::entity::character::CharacterEntity; +use entity::character::CharacterEntity; //use crate::ship::items::{CharacterInventory, CharacterBank}; use crate::ship::items::bank::BankState; use crate::ship::items::inventory::InventoryState; -use crate::entity::item::Meseta; +use entity::item::Meseta; #[derive(Default)] diff --git a/src/ship/chatcommand.rs b/src/ship/chatcommand.rs index 97d5054..7d2c643 100644 --- a/src/ship/chatcommand.rs +++ b/src/ship/chatcommand.rs @@ -1,10 +1,10 @@ use libpso::packet::ship::PlayerChat; -use crate::entity::gateway::EntityGateway; +use entity::gateway::EntityGateway; use crate::common::serverstate::ClientId; use crate::ship::ship::{ShipServerState, SendShipPacket}; use crate::ship::client::Clients; use crate::ship::items::state::ItemState; -use crate::entity::item::{BankName, BankIdentifier}; +use entity::item::{BankName, BankIdentifier}; use crate::ship::packet::builder::message::bank_item_list; async fn default_bank<'a, EG>(id: ClientId, diff --git a/src/ship/client.rs b/src/ship/client.rs index 5495309..58f75f7 100644 --- a/src/ship/client.rs +++ b/src/ship/client.rs @@ -7,13 +7,13 @@ use libpso::packet::ship::*; use libpso::packet::login::Session; use crate::common::serverstate::ClientId; -use crate::entity::account::{UserAccountEntity, UserSettingsEntity}; -use crate::entity::character::CharacterEntity; -use crate::entity::item; +use entity::account::{UserAccountEntity, UserSettingsEntity}; +use entity::character::CharacterEntity; +use entity::item; use crate::ship::ship::ShipError; use crate::ship::items; -use crate::ship::map::MapArea; +use maps::area::MapArea; use crate::ship::shops::{WeaponShopItem, ToolShopItem, ArmorShopItem}; diff --git a/src/ship/drops/box_drop_table.rs b/src/ship/drops/box_drop_table.rs index f507d27..4ad1e60 100644 --- a/src/ship/drops/box_drop_table.rs +++ b/src/ship/drops/box_drop_table.rs @@ -2,18 +2,18 @@ use rand::{Rng}; use rand::distributions::{WeightedIndex, Distribution}; use serde::{Serialize, Deserialize}; -use crate::entity::character::SectionID; -use crate::ship::room::{Difficulty, Episode}; -use crate::ship::map::MapArea; +use entity::character::SectionID; +use maps::room::{Difficulty, Episode}; +use maps::area::MapArea; use crate::ship::drops::{ItemDropType, load_data_file}; -use crate::ship::map::{MapObject, MapObjectType, FixedBoxDropType}; +use maps::object::{MapObject, MapObjectType, FixedBoxDropType}; use crate::ship::drops::rare_drop_table::{RareDropTable, RareDropItem}; use crate::ship::drops::generic_weapon::GenericWeaponTable; use crate::ship::drops::generic_armor::GenericArmorTable; use crate::ship::drops::generic_shield::GenericShieldTable; use crate::ship::drops::generic_unit::GenericUnitTable; use crate::ship::drops::tool_table::ToolTable; -use crate::entity::item::ItemDetail; +use entity::item::ItemDetail; #[derive(Debug, Serialize, Deserialize)] struct BoxDropRate { @@ -204,7 +204,7 @@ impl BoxDropTable { FixedBoxDropType::Specific(value) => { let mut buf: [u8; 16] = [0; 16]; buf[0..4].copy_from_slice(&u32::to_be_bytes(value)); - ItemDetail::parse_item_from_bytes(buf) + ItemDropType::parse_item_from_bytes(buf) }, } } diff --git a/src/ship/drops/generic_armor.rs b/src/ship/drops/generic_armor.rs index 2bf5895..80e4761 100644 --- a/src/ship/drops/generic_armor.rs +++ b/src/ship/drops/generic_armor.rs @@ -1,12 +1,12 @@ use std::collections::HashMap; use serde::{Serialize, Deserialize}; -use rand::{Rng}; +use rand::Rng; use rand::distributions::{WeightedIndex, Distribution}; -use crate::entity::item::armor::{ArmorType, Armor}; -use crate::ship::room::{Difficulty, Episode}; -use crate::ship::map::MapArea; -use crate::entity::character::SectionID; +use entity::character::SectionID; +use entity::item::armor::{ArmorType, Armor}; +use maps::room::{Difficulty, Episode}; +use maps::area::MapArea; use crate::ship::drops::{ItemDropType, load_data_file}; use crate::ship::item_stats::{armor_stats, ArmorStats}; diff --git a/src/ship/drops/generic_shield.rs b/src/ship/drops/generic_shield.rs index 9eec585..fd5752e 100644 --- a/src/ship/drops/generic_shield.rs +++ b/src/ship/drops/generic_shield.rs @@ -1,12 +1,12 @@ use std::collections::HashMap; use serde::{Serialize, Deserialize}; -use rand::{Rng}; +use rand::Rng; use rand::distributions::{WeightedIndex, Distribution}; -use crate::entity::item::shield::{ShieldType, Shield}; -use crate::ship::room::{Difficulty, Episode}; -use crate::ship::map::MapArea; -use crate::entity::character::SectionID; +use entity::item::shield::{ShieldType, Shield}; +use entity::character::SectionID; +use maps::room::{Difficulty, Episode}; +use maps::area::MapArea; use crate::ship::drops::{ItemDropType, load_data_file}; use crate::ship::item_stats::{shield_stats, ShieldStats}; diff --git a/src/ship/drops/generic_unit.rs b/src/ship/drops/generic_unit.rs index 73bc4a6..137f7d0 100644 --- a/src/ship/drops/generic_unit.rs +++ b/src/ship/drops/generic_unit.rs @@ -1,12 +1,12 @@ use std::collections::BTreeMap; use serde::{Serialize, Deserialize}; -use rand::{Rng}; +use rand::Rng; use rand::seq::IteratorRandom; -use crate::entity::item::unit::{UnitType, Unit, UnitModifier}; -use crate::ship::room::{Difficulty, Episode}; -use crate::ship::map::MapArea; -use crate::entity::character::SectionID; +use entity::character::SectionID; +use entity::item::unit::{UnitType, Unit, UnitModifier}; +use maps::room::{Difficulty, Episode}; +use maps::area::MapArea; use crate::ship::drops::{ItemDropType, load_data_file}; use crate::ship::item_stats::{unit_stats, UnitStats}; diff --git a/src/ship/drops/generic_weapon.rs b/src/ship/drops/generic_weapon.rs index d1fb2bb..38290e7 100644 --- a/src/ship/drops/generic_weapon.rs +++ b/src/ship/drops/generic_weapon.rs @@ -1,13 +1,13 @@ use std::collections::{HashMap, BTreeMap}; use serde::{Serialize, Deserialize}; -use rand::{Rng}; +use rand::Rng; use rand::distributions::{WeightedIndex, Distribution}; use rand::seq::SliceRandom; -use crate::entity::item::weapon::{Weapon, WeaponType, Attribute, WeaponAttribute, WeaponSpecial}; -use crate::ship::room::{Difficulty, Episode}; -use crate::ship::map::MapArea; -use crate::entity::character::SectionID; +use entity::character::SectionID; +use entity::item::weapon::{Weapon, WeaponType, Attribute, WeaponAttribute, WeaponSpecial}; +use maps::room::{Difficulty, Episode}; +use maps::area::MapArea; use crate::ship::drops::{ItemDropType, load_data_file}; diff --git a/src/ship/drops/mod.rs b/src/ship/drops/mod.rs index 5d8062c..5c228e0 100644 --- a/src/ship/drops/mod.rs +++ b/src/ship/drops/mod.rs @@ -22,10 +22,10 @@ use std::io::Read; use serde::{Serialize, Deserialize}; use rand::{Rng, SeedableRng}; -use crate::ship::monster::MonsterType; -use crate::ship::room::{Difficulty, Episode}; -use crate::ship::map::MapArea; -use crate::entity::character::SectionID; +use maps::monster::MonsterType; +use maps::room::{Difficulty, Episode}; +use maps::area::MapArea; +use entity::character::SectionID; use crate::ship::drops::generic_weapon::GenericWeaponTable; use crate::ship::drops::generic_armor::GenericArmorTable; use crate::ship::drops::generic_shield::GenericShieldTable; @@ -33,8 +33,8 @@ use crate::ship::drops::generic_unit::GenericUnitTable; use crate::ship::drops::tool_table::ToolTable; use crate::ship::drops::rare_drop_table::RareDropTable; use crate::ship::drops::box_drop_table::BoxDropTable; -use crate::ship::map::MapObject; -use crate::entity::item::{weapon, armor, shield, unit, mag, tool, tech}; +use maps::object::MapObject; +use entity::item::{ItemType, weapon, armor, shield, unit, mag, tool, tech, esweapon}; fn data_file_path(episode: Episode, difficulty: Difficulty, section_id: SectionID, filename: &str) -> PathBuf { @@ -55,18 +55,6 @@ pub fn load_data_file(episode: Episode, difficul toml::from_str::(s.as_str()).unwrap() } -// this is just copypaste -pub fn load_rare_monster_file(episode: Episode) -> T { - // TODO: where does the rare monster toml file actually live - let mut path = PathBuf::from("data/battle_param/"); - path.push(episode.to_string().to_lowercase() + "_rare_monster.toml"); - - let mut f = File::open(path).unwrap(); - let mut s = String::new(); - f.read_to_string(&mut s); - toml::from_str::(s.as_str()).unwrap() -} - #[derive(Debug, Serialize, Deserialize, Copy, Clone)] pub enum MonsterDropType { #[serde(rename = "weapon")] @@ -102,6 +90,28 @@ pub enum ItemDropType { Meseta(u32), } +impl ItemDropType { + pub fn parse_item_from_bytes(data: [u8; 16]) -> Option { + let item_type = weapon::WeaponType::parse_type([data[0],data[1],data[2]]).map(ItemType::Weapon) + .or_else(|_| armor::ArmorType::parse_type([data[0],data[1],data[2]]).map(ItemType::Armor)) + .or_else(|_| shield::ShieldType::parse_type([data[0],data[1],data[2]]).map(ItemType::Shield)) + .or_else(|_| unit::UnitType::parse_type([data[0],data[1],data[2]]).map(ItemType::Unit)) + .or_else(|_| mag::MagType::parse_type([data[0],data[1],data[2]]).map(ItemType::Mag)) + .or_else(|_| tool::ToolType::parse_type([data[0],data[1],data[2]]).map(ItemType::Tool)) + .or_else(|_| esweapon::ESWeaponType::parse_type([data[0],data[1],data[2]]).map(ItemType::ESWeapon)).ok()?; + + match item_type { + ItemType::Weapon(_w) => Some(ItemDropType::Weapon(weapon::Weapon::from_bytes(data).ok()?)), + ItemType::Armor(_a) => Some(ItemDropType::Armor(armor::Armor::from_bytes(data).ok()?)), + ItemType::Shield(_s) => Some(ItemDropType::Shield(shield::Shield::from_bytes(data).ok()?)), + ItemType::Unit(_u) => Some(ItemDropType::Unit(unit::Unit::from_bytes(data).ok()?)), + ItemType::Mag(_m) => Some(ItemDropType::Mag(mag::Mag::from_bytes(data).ok()?)), + ItemType::Tool(_t) => Some(ItemDropType::Tool(tool::Tool::from_bytes(data).ok()?)), + _ => None, + } + } +} + #[derive(Clone, Debug)] pub struct ItemDrop { pub map_area: MapArea, diff --git a/src/ship/drops/rare_drop_table.rs b/src/ship/drops/rare_drop_table.rs index 51151ba..0eb6cc8 100644 --- a/src/ship/drops/rare_drop_table.rs +++ b/src/ship/drops/rare_drop_table.rs @@ -1,16 +1,16 @@ use std::collections::HashMap; use rand::Rng; use serde::{Serialize, Deserialize}; -use crate::entity::item::weapon::{Weapon, WeaponType}; -use crate::entity::item::armor::{Armor, ArmorType}; -use crate::entity::item::shield::{Shield, ShieldType}; -use crate::entity::item::unit::{Unit, UnitType}; -use crate::entity::item::tool::{Tool, ToolType}; -use crate::entity::item::mag::{Mag, MagType}; -use crate::entity::character::SectionID; -use crate::ship::monster::MonsterType; -use crate::ship::room::{Difficulty, Episode}; -use crate::ship::map::MapArea; +use entity::item::weapon::{Weapon, WeaponType}; +use entity::item::armor::{Armor, ArmorType}; +use entity::item::shield::{Shield, ShieldType}; +use entity::item::unit::{Unit, UnitType}; +use entity::item::tool::{Tool, ToolType}; +use entity::item::mag::{Mag, MagType}; +use entity::character::SectionID; +use maps::monster::MonsterType; +use maps::room::{Difficulty, Episode}; +use maps::area::MapArea; use crate::ship::drops::{ItemDropType, load_data_file}; use crate::ship::drops::generic_weapon::AttributeTable; use crate::ship::drops::generic_armor::GenericArmorTable; diff --git a/src/ship/drops/tech_table.rs b/src/ship/drops/tech_table.rs index 6e6396f..79bf095 100644 --- a/src/ship/drops/tech_table.rs +++ b/src/ship/drops/tech_table.rs @@ -3,10 +3,10 @@ use serde::{Serialize, Deserialize}; use rand::{Rng}; use rand::distributions::{WeightedIndex, Distribution}; -use crate::entity::item::tech::{Technique, TechniqueDisk}; -use crate::ship::room::{Difficulty, Episode}; -use crate::ship::map::MapArea; -use crate::entity::character::SectionID; +use entity::item::tech::{Technique, TechniqueDisk}; +use maps::room::{Difficulty, Episode}; +use maps::area::MapArea; +use entity::character::SectionID; use crate::ship::drops::{ItemDropType, load_data_file}; diff --git a/src/ship/drops/tool_table.rs b/src/ship/drops/tool_table.rs index 69a14cd..0ce9e6d 100644 --- a/src/ship/drops/tool_table.rs +++ b/src/ship/drops/tool_table.rs @@ -1,12 +1,12 @@ -use std::collections::{BTreeMap}; +use std::collections::BTreeMap; use serde::{Serialize, Deserialize}; -use rand::{Rng}; +use rand::Rng; use rand::distributions::{WeightedIndex, Distribution}; -use crate::entity::item::tool::{Tool, ToolType}; -use crate::ship::room::{Difficulty, Episode}; -use crate::ship::map::MapArea; -use crate::entity::character::SectionID; +use entity::item::tool::{Tool, ToolType}; +use maps::room::{Difficulty, Episode}; +use maps::area::MapArea; +use entity::character::SectionID; use crate::ship::drops::{ItemDropType, load_data_file}; use crate::ship::drops::tech_table::TechniqueTable; diff --git a/src/ship/item_stats.rs b/src/ship/item_stats.rs index 919c076..13d0855 100644 --- a/src/ship/item_stats.rs +++ b/src/ship/item_stats.rs @@ -4,13 +4,13 @@ use serde::{Serialize, Deserialize}; use std::fs::File; use std::io::Read; -use crate::entity::item::weapon::WeaponType; -use crate::entity::item::armor::ArmorType; -use crate::entity::item::shield::ShieldType; -use crate::entity::item::unit::UnitType; -use crate::entity::item::mag::MagType; -use crate::entity::item::tool::ToolType; -use crate::entity::item::tech::Technique; +use entity::item::weapon::WeaponType; +use entity::item::armor::ArmorType; +use entity::item::shield::ShieldType; +use entity::item::unit::UnitType; +use entity::item::mag::MagType; +use entity::item::tool::ToolType; +use entity::item::tech::Technique; lazy_static::lazy_static! { diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index 0c06691..2359950 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -1,6 +1,6 @@ // TODO: replace various u32s and usizes denoting item amounts for ItemAmount(u32) for consistency use crate::ship::items::ClientItemId; -use crate::entity::item::{Meseta, ItemNote}; +use entity::item::{Meseta, ItemNote}; use async_std::sync::Arc; use std::future::Future; use futures::future::BoxFuture; @@ -9,12 +9,12 @@ use std::iter::IntoIterator; use anyhow::Context; use libpso::packet::{ship::Message, messages::GameMessage}; -use crate::entity::character::{CharacterEntity, CharacterEntityId}; -use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction}; -use crate::entity::item::{ItemDetail, NewItemEntity, TradeId, ItemModifier}; -use crate::entity::item::tool::Tool; -use crate::entity::room::RoomEntityId; -use crate::ship::map::MapArea; +use entity::character::{CharacterEntity, CharacterEntityId}; +use entity::gateway::{EntityGateway, EntityGatewayTransaction}; +use entity::item::{ItemDetail, NewItemEntity, TradeId, ItemModifier}; +use entity::item::tool::Tool; +use entity::room::RoomEntityId; +use maps::area::MapArea; use crate::ship::ship::SendShipPacket; use crate::ship::items::state::{ItemStateProxy, ItemStateError, AddItemResult, StackedItemDetail, IndividualItemDetail}; use crate::ship::items::bank::{BankItem, BankItemDetail}; @@ -25,7 +25,7 @@ use crate::ship::shops::ShopItem; use crate::ship::drops::{ItemDrop, ItemDropType}; use crate::ship::packet::builder; use crate::ship::location::AreaClient; -use crate::ship::monster::MonsterType; +use maps::monster::MonsterType; pub enum TriggerCreateItem { Yes, diff --git a/src/ship/items/apply_item.rs b/src/ship/items/apply_item.rs index 4c1a636..9c7e3c2 100644 --- a/src/ship/items/apply_item.rs +++ b/src/ship/items/apply_item.rs @@ -4,13 +4,13 @@ use thiserror::Error; use anyhow::Context; use rand::SeedableRng; use rand::distributions::{WeightedIndex, Distribution}; -use crate::entity::gateway::{EntityGateway, GatewayError}; -use crate::entity::character::{CharacterEntity, TechLevel}; -use crate::entity::item::mag::{MagCell, MagCellError}; -use crate::entity::item::tool::{Tool, ToolType}; -use crate::entity::item::tech::TechniqueDisk; -use crate::entity::item::{ItemDetail, ItemEntityId}; -use crate::entity::item::weapon::WeaponModifier; +use entity::gateway::{EntityGateway, GatewayError}; +use entity::character::{CharacterEntity, TechLevel}; +use entity::item::mag::{MagCell, MagCellError}; +use entity::item::tool::{Tool, ToolType}; +use entity::item::tech::TechniqueDisk; +use entity::item::{ItemDetail, ItemEntityId}; +use entity::item::weapon::WeaponModifier; use crate::ship::items::state::ItemStateProxy; use crate::ship::items::inventory::InventoryItemDetail; diff --git a/src/ship/items/bank.rs b/src/ship/items/bank.rs index 73f0e10..f6d12cd 100644 --- a/src/ship/items/bank.rs +++ b/src/ship/items/bank.rs @@ -1,12 +1,12 @@ use std::cmp::Ordering; use libpso::character::character; use crate::ship::items::ClientItemId; -use crate::entity::item::{Meseta, ItemEntityId, ItemDetail, ItemEntity, BankEntity, BankItemEntity}; +use entity::item::{Meseta, ItemEntityId, ItemDetail, ItemEntity, BankEntity, BankItemEntity}; use std::future::Future; use async_std::sync::{Arc, Mutex}; -use crate::entity::character::CharacterEntityId; -use crate::entity::item::BankIdentifier; +use entity::character::CharacterEntityId; +use entity::item::BankIdentifier; use crate::ship::items::state::ItemStateError; use crate::ship::items::state::{IndividualItemDetail, StackedItemDetail, AddItemResult}; use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail}; diff --git a/src/ship/items/floor.rs b/src/ship/items/floor.rs index b0e968f..6d03133 100644 --- a/src/ship/items/floor.rs +++ b/src/ship/items/floor.rs @@ -1,10 +1,10 @@ use crate::ship::items::ClientItemId; -use crate::entity::item::{Meseta, ItemEntityId, ItemDetail}; +use entity::item::{Meseta, ItemEntityId, ItemDetail}; use std::future::Future; -use crate::ship::map::MapArea; -use crate::entity::character::CharacterEntityId; -use crate::entity::item::mag::Mag; +use maps::area::MapArea; +use entity::character::CharacterEntityId; +use entity::item::mag::Mag; use crate::ship::items::state::ItemStateError; use crate::ship::items::state::{IndividualItemDetail, StackedItemDetail}; diff --git a/src/ship/items/inventory.rs b/src/ship/items/inventory.rs index da131d8..ca0e51d 100644 --- a/src/ship/items/inventory.rs +++ b/src/ship/items/inventory.rs @@ -1,14 +1,14 @@ use std::cmp::Ordering; use libpso::character::character; use crate::ship::items::ClientItemId; -use crate::entity::item::{Meseta, ItemEntityId, ItemDetail, ItemEntity, InventoryEntity, InventoryItemEntity, EquippedEntity}; +use entity::item::{Meseta, ItemEntityId, ItemDetail, ItemEntity, InventoryEntity, InventoryItemEntity, EquippedEntity}; use std::future::Future; use async_std::sync::{Arc, Mutex}; -use crate::entity::character::CharacterEntityId; -use crate::entity::item::tool::ToolType; -use crate::entity::item::mag::Mag; -use crate::entity::item::weapon::Weapon; +use entity::character::CharacterEntityId; +use entity::item::tool::ToolType; +use entity::item::mag::Mag; +use entity::item::weapon::Weapon; use crate::ship::shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem}; use crate::ship::items::state::ItemStateError; use crate::ship::items::state::{IndividualItemDetail, StackedItemDetail, AddItemResult}; diff --git a/src/ship/items/state.rs b/src/ship/items/state.rs index 906762a..9058c05 100644 --- a/src/ship/items/state.rs +++ b/src/ship/items/state.rs @@ -4,12 +4,12 @@ use async_std::sync::{Arc, RwLock, Mutex}; use futures::stream::{FuturesOrdered, StreamExt}; use anyhow::Context; -use crate::entity::gateway::{EntityGateway, GatewayError}; -use crate::entity::character::{CharacterEntity, CharacterEntityId}; -use crate::entity::item::{ItemEntityId, ItemDetail, ItemEntity, InventoryItemEntity, BankItemEntity, BankIdentifier}; -use crate::entity::item::tool::Tool; -use crate::entity::item::weapon::Weapon; -use crate::entity::item::mag::Mag; +use entity::gateway::{EntityGateway, GatewayError}; +use entity::character::{CharacterEntity, CharacterEntityId}; +use entity::item::{ItemEntityId, ItemDetail, ItemEntity, InventoryItemEntity, BankItemEntity, BankIdentifier}; +use entity::item::tool::Tool; +use entity::item::weapon::Weapon; +use entity::item::mag::Mag; use crate::ship::drops::ItemDrop; use crate::ship::items::ClientItemId; use crate::ship::items::inventory::{Inventory, InventoryItem, InventoryItemDetail, InventoryError, InventoryState}; diff --git a/src/ship/items/tasks.rs b/src/ship/items/tasks.rs index 0c3f948..f224f4c 100644 --- a/src/ship/items/tasks.rs +++ b/src/ship/items/tasks.rs @@ -1,13 +1,13 @@ use futures::future::BoxFuture; use crate::ship::items::ClientItemId; -use crate::entity::item::Meseta; +use entity::item::Meseta; use crate::ship::ship::SendShipPacket; -use crate::ship::map::MapArea; -use crate::entity::character::{CharacterEntity, CharacterEntityId}; -use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction}; -use crate::entity::item::ItemModifier; -use crate::entity::room::RoomEntityId; +use maps::area::MapArea; +use entity::character::{CharacterEntity, CharacterEntityId}; +use entity::gateway::{EntityGateway, EntityGatewayTransaction}; +use entity::item::ItemModifier; +use entity::room::RoomEntityId; use crate::ship::items::state::{ItemState, ItemStateProxy, IndividualItemDetail}; use crate::ship::items::itemstateaction::{ItemStateAction, ItemAction}; use crate::ship::items::inventory::InventoryItem; @@ -16,7 +16,7 @@ use crate::ship::shops::ShopItem; use crate::ship::trade::TradeItem; use crate::ship::location::AreaClient; use crate::ship::drops::ItemDrop; -use crate::ship::monster::MonsterType; +use maps::monster::MonsterType; use crate::ship::items::actions; diff --git a/src/ship/map/mod.rs b/src/ship/map/mod.rs deleted file mode 100644 index 693fd46..0000000 --- a/src/ship/map/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -pub mod area; -pub mod enemy; -pub mod object; -pub mod variant; -pub mod maps; - -// TODO: don't just forward everything to the module scope -pub use area::*; -pub use enemy::*; -pub use object::*; -pub use variant::*; -pub use maps::*; diff --git a/src/ship/mod.rs b/src/ship/mod.rs index c58edb6..3978099 100644 --- a/src/ship/mod.rs +++ b/src/ship/mod.rs @@ -6,8 +6,8 @@ pub mod client; pub mod room; pub mod items; pub mod item_stats; -pub mod map; -pub mod monster; +//pub mod map; +//pub mod monster; pub mod drops; pub mod packet; pub mod quests; diff --git a/src/ship/packet/builder/message.rs b/src/ship/packet/builder/message.rs index ac60484..f83ebbd 100644 --- a/src/ship/packet/builder/message.rs +++ b/src/ship/packet/builder/message.rs @@ -1,6 +1,6 @@ use libpso::packet::messages::*; use libpso::packet::ship::*; -use crate::entity::item; +use entity::item; use crate::common::leveltable::CharacterStats; use crate::ship::ship::{ShipError}; use crate::ship::items::ClientItemId; diff --git a/src/ship/packet/handler/auth.rs b/src/ship/packet/handler/auth.rs index 698de75..bd0c846 100644 --- a/src/ship/packet/handler/auth.rs +++ b/src/ship/packet/handler/auth.rs @@ -3,7 +3,7 @@ use libpso::packet::ship::*; use crate::common::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, ShipError, ClientState, Clients}; use crate::login::login::get_login_status; -use crate::entity::gateway::EntityGateway; +use entity::gateway::EntityGateway; use crate::ship::items::state::ItemState; use crate::common::interserver::ShipMessage; diff --git a/src/ship/packet/handler/communication.rs b/src/ship/packet/handler/communication.rs index c0ac3e5..2f7ef43 100644 --- a/src/ship/packet/handler/communication.rs +++ b/src/ship/packet/handler/communication.rs @@ -2,7 +2,7 @@ use libpso::packet::ship::*; use crate::common::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, Clients}; use crate::ship::location::{ClientLocation}; -use crate::entity::gateway::EntityGateway; +use entity::gateway::EntityGateway; use futures::future::join_all; diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index 3c914e8..0886f79 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/src/ship/packet/handler/direct_message.rs @@ -10,8 +10,8 @@ use crate::ship::location::ClientLocation; use crate::ship::drops::ItemDrop; use crate::ship::room::Rooms; use crate::ship::items::ClientItemId; -use crate::entity::gateway::EntityGateway; -use crate::entity::item; +use entity::gateway::EntityGateway; +use entity::item; use libpso::utf8_to_utf16_array; use crate::ship::packet::builder; use crate::ship::shops::{ShopItem, ToolShopItem, ArmorShopItem}; diff --git a/src/ship/packet/handler/lobby.rs b/src/ship/packet/handler/lobby.rs index d5506c4..ae95afb 100644 --- a/src/ship/packet/handler/lobby.rs +++ b/src/ship/packet/handler/lobby.rs @@ -7,9 +7,9 @@ use crate::ship::character::{FullCharacterBytesBuilder}; use crate::ship::location::{ClientLocation, LobbyId, RoomLobby, ClientLocationError, RoomId}; use crate::ship::packet; use crate::ship::items::state::ItemState; -use crate::entity::gateway::EntityGateway; -use crate::entity::room::RoomNote; -use crate::ship::map::MapArea; +use entity::gateway::EntityGateway; +use entity::room::RoomNote; +use maps::area::MapArea; use futures::future::join_all; // this function needs a better home diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index f380d14..a46b90c 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -1,7 +1,7 @@ use libpso::packet::ship::*; use libpso::packet::messages::*; -use crate::entity::gateway::EntityGateway; -use crate::entity::item::Meseta; +use entity::gateway::EntityGateway; +use entity::item::Meseta; use crate::common::serverstate::ClientId; use crate::common::leveltable::LEVEL_TABLE; use crate::ship::ship::{SendShipPacket, ShipError, Clients, ItemDropLocation}; diff --git a/src/ship/packet/handler/quest.rs b/src/ship/packet/handler/quest.rs index 1c8c31e..b219684 100644 --- a/src/ship/packet/handler/quest.rs +++ b/src/ship/packet/handler/quest.rs @@ -4,7 +4,7 @@ use libpso::packet::ship::*; use crate::common::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, ShipError, Clients, ShipEvent}; use crate::ship::room::Rooms; -use crate::ship::map::enemy::RareMonsterAppearTable; +use maps::enemy::RareMonsterAppearTable; use crate::ship::location::{ClientLocation}; use crate::ship::packet::builder::quest; use libpso::util::array_to_utf8; @@ -118,7 +118,7 @@ pub async fn player_chose_quest(id: ClientId, .clone(); let rare_monster_table = RareMonsterAppearTable::new(room.mode.episode()); - room.maps.set_quest_data(quest.enemies.clone(), quest.objects.clone(), &rare_monster_table, event); + room.maps.set_quest_data(quest.enemies.clone(), quest.objects.clone(), &rare_monster_table, event.rare_enemy_event()); room.map_areas = quest.map_areas.clone(); let bin = quest::quest_header(&questmenuselect, &quest.bin_blob, "bin"); diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 9198c63..cf5d6af 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -1,4 +1,4 @@ -use std::convert::{TryFrom, Into}; +use std::convert::Into; use futures::stream::StreamExt; use async_std::sync::Arc; @@ -7,13 +7,15 @@ use libpso::packet::ship::*; use libpso::packet::messages::*; use crate::common::serverstate::ClientId; use crate::common::leveltable::LEVEL_TABLE; -use crate::entity::gateway::EntityGateway; -use crate::entity::character::SectionID; -use crate::entity::room::{NewRoomEntity, RoomEntityMode, RoomNote}; +use entity::gateway::EntityGateway; +use entity::character::SectionID; +use entity::room::{NewRoomEntity, RoomEntityMode, RoomNote}; use crate::ship::drops::DropTable; use crate::ship::ship::{SendShipPacket, Clients, ShipEvent}; -use crate::ship::room::{Rooms, Episode, Difficulty, RoomState, RoomMode}; -use crate::ship::map::Maps; +use crate::ship::room::{Rooms, RoomState, RoomCreationError}; +use maps::room::{Episode, Difficulty, RoomMode}; +use maps::enemy::RareEnemyEvent; +use maps::maps::Maps; use crate::ship::location::{ClientLocation, RoomId, RoomLobby, GetAreaError}; use crate::ship::packet::builder; use crate::ship::items::state::ItemState; @@ -26,7 +28,7 @@ pub async fn create_room(id: ClientId, clients: &Clients, item_state: &mut ItemState, rooms: &Rooms, - map_builder: Arc Maps + Send + Sync>>, + map_builder: Arc) -> Maps + Send + Sync>>, drop_table_builder: Arc DropTable + Send + Sync>>, event: ShipEvent) -> Result, anyhow::Error> @@ -36,7 +38,8 @@ where let level = clients.with(id, |client| Box::pin(async move { LEVEL_TABLE.get_level_from_exp(client.character.char_class, client.character.exp) })).await?; - let difficulty = Difficulty::try_from(create_room.difficulty)?; + let difficulty = create_room.difficulty.try_into() + .map_err(|()| RoomCreationError::InvalidDifficulty(create_room.difficulty))?; match difficulty { Difficulty::Ultimate if level < 80 => { return Ok(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto create Ultimate rooms.".into())))]) @@ -64,8 +67,9 @@ where (0, 0, 1) => RoomEntityMode::Single, _ => RoomEntityMode::Multi, }; - let episode = create_room.episode.try_into()?; - let difficulty = create_room.difficulty.try_into()?; + let episode = create_room.episode.try_into() + .map_err(|()| RoomCreationError::InvalidEpisode(create_room.episode))?; + //let difficulty = create_room.difficulty.try_into()?; let room = clients.with(id, |client| { let mut item_state = item_state.clone(); diff --git a/src/ship/packet/handler/settings.rs b/src/ship/packet/handler/settings.rs index de7bfaa..c8ebd52 100644 --- a/src/ship/packet/handler/settings.rs +++ b/src/ship/packet/handler/settings.rs @@ -1,7 +1,7 @@ use libpso::packet::ship::*; use crate::common::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, Clients}; -use crate::entity::gateway::EntityGateway; +use entity::gateway::EntityGateway; pub async fn update_config(id: ClientId, update_config: UpdateConfig, diff --git a/src/ship/packet/handler/trade.rs b/src/ship/packet/handler/trade.rs index c1cb2d0..f3128d0 100644 --- a/src/ship/packet/handler/trade.rs +++ b/src/ship/packet/handler/trade.rs @@ -8,11 +8,11 @@ use crate::ship::items::ClientItemId; use crate::ship::items::state::{ItemState, ItemStateError}; use crate::ship::items::inventory::InventoryItemDetail; use crate::ship::trade::{TradeItem, TradeState, TradeStatus}; -use crate::entity::gateway::EntityGateway; +use entity::gateway::EntityGateway; use crate::ship::packet::builder; use crate::ship::items::tasks::trade_items; use crate::ship::location::{AreaClient, RoomId}; -use crate::entity::item::Meseta; +use entity::item::Meseta; use crate::ship::trade::ClientTradeState; pub const MESETA_ITEM_ID: ClientItemId = ClientItemId(0xFFFFFF01); diff --git a/src/ship/quests.rs b/src/ship/quests.rs index 4f5eb26..91e5d4d 100644 --- a/src/ship/quests.rs +++ b/src/ship/quests.rs @@ -10,9 +10,12 @@ use serde::{Serialize, Deserialize}; use ages_prs::{LegacyPrsDecoder, LegacyPrsEncoder}; use byteorder::{LittleEndian, ReadBytesExt}; use libpso::util::array_to_utf16; -use crate::ship::map::{MapArea, MapAreaError, MapObject, MapEnemy, enemy_data_from_stream, objects_from_stream}; -use crate::ship::room::{Episode, RoomMode}; -use crate::ship::map::area::{MapAreaLookup, MapAreaLookupBuilder}; +use maps::area::{MapArea, MapAreaError}; +use maps::object::MapObject; +use maps::enemy::MapEnemy; +use maps::maps::{objects_from_stream, enemy_data_from_stream}; +use maps::room::{Episode, RoomMode}; +use maps::area::{MapAreaLookup, MapAreaLookupBuilder}; #[derive(Debug, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)] @@ -101,7 +104,7 @@ fn quest_episode(bin: &[u8]) -> Option { for bytes in bin.windows(3) { // set_episode if bytes[0] == 0xF8 && bytes[1] == 0xBC { - return Episode::from_quest(bytes[2]).ok() + return Episode::from_quest(bytes[2]) } } None diff --git a/src/ship/room.rs b/src/ship/room.rs index b3a03c2..441feb5 100644 --- a/src/ship/room.rs +++ b/src/ship/room.rs @@ -1,5 +1,5 @@ use std::collections::HashMap; -use std::convert::{From, Into, TryFrom}; +use std::convert::{From, Into}; use async_std::sync::{Arc, RwLock, RwLockReadGuard}; use futures::future::BoxFuture; use futures::stream::{FuturesOrdered, Stream}; @@ -7,16 +7,19 @@ use futures::stream::{FuturesOrdered, Stream}; use thiserror::Error; use rand::Rng; -use crate::ship::map::Maps; +use maps::maps::Maps; use crate::ship::drops::DropTable; -use crate::entity::character::SectionID; -use crate::entity::room::{RoomEntityId, RoomEntityMode}; -use crate::ship::monster::{load_monster_stats_table, MonsterType, MonsterStats}; -use crate::ship::map::area::MapAreaLookup; +use entity::character::SectionID; +use entity::room::{RoomEntityId, RoomEntityMode}; +use maps::monster::{load_monster_stats_table, MonsterType, MonsterStats}; +use maps::area::MapAreaLookup; +use maps::enemy::RareEnemyEvent; use crate::ship::quests; use crate::ship::ship::{ShipError, ShipEvent}; use crate::ship::location::{MAX_ROOMS, RoomId}; +use maps::room::{Episode, Difficulty, RoomMode}; + #[derive(Clone)] pub struct Rooms([Arc>>; MAX_ROOMS]); @@ -123,156 +126,7 @@ pub enum RoomCreationError { CouldNotLoadQuests, } -#[derive(Debug, Copy, Clone, derive_more::Display)] -pub enum Episode { - #[display(fmt="ep1")] - One, - #[display(fmt="ep2")] - Two, - #[display(fmt="ep4")] - Four, -} - -#[derive(Debug, Copy, Clone)] -pub enum PlayerMode{ - Single, - Multi, -} - -impl PlayerMode { - pub fn value(&self) -> u8 { - match self { - PlayerMode::Single => 1, - PlayerMode::Multi => 0, - } - } -} - -impl TryFrom for Episode { - type Error = RoomCreationError; - - fn try_from(value: u8) -> Result { - match value { - 1 => Ok(Episode::One), - 2 => Ok(Episode::Two), - 3 => Ok(Episode::Four), - _ => Err(RoomCreationError::InvalidEpisode(value)) - } - } -} -impl From for u8 { - fn from(other: Episode) -> u8 { - match other { - Episode::One => 1, - Episode::Two => 2, - Episode::Four => 3, - } - } -} - -impl Episode { - pub fn from_quest(value: u8) -> Result { - match value { - 0 => Ok(Episode::One), - 1 => Ok(Episode::Two), - 2 => Ok(Episode::Four), - _ => Err(RoomCreationError::InvalidEpisode(value)) - } - } -} - -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, derive_more::Display)] -pub enum Difficulty { - Normal, - Hard, - VeryHard, - Ultimate, -} - -impl TryFrom for Difficulty { - type Error = RoomCreationError; - - fn try_from(value: u8) -> Result { - match value { - 0 => Ok(Difficulty::Normal), - 1 => Ok(Difficulty::Hard), - 2 => Ok(Difficulty::VeryHard), - 3 => Ok(Difficulty::Ultimate), - _ => Err(RoomCreationError::InvalidDifficulty(value)) - } - } -} - -impl From for u8 { - fn from(other: Difficulty) -> u8 { - match other { - Difficulty::Normal => 0, - Difficulty::Hard => 1, - Difficulty::VeryHard => 2, - Difficulty::Ultimate => 3, - } - } -} - -#[derive(Debug, Copy, Clone, derive_more::Display)] -pub enum RoomMode { - #[display(fmt="single")] - Single { - episode: Episode, - difficulty: Difficulty, - }, - #[display(fmt="multi")] - Multi { - episode: Episode, - difficulty: Difficulty, - }, - #[display(fmt="challenge")] - Challenge { - episode: Episode, - }, - #[display(fmt="battle")] - Battle { - episode: Episode, - difficulty: Difficulty, - } -} - - -impl RoomMode { - pub fn difficulty(&self) -> Difficulty { - match self { - RoomMode::Single {difficulty, ..} => *difficulty, - RoomMode::Multi {difficulty, ..} => *difficulty, - RoomMode::Battle {difficulty, ..} => *difficulty, - RoomMode::Challenge {..} => Difficulty::Normal, - } - } - - pub fn episode(&self) -> Episode { - match self { - RoomMode::Single {episode, ..} => *episode, - RoomMode::Multi {episode, ..} => *episode, - RoomMode::Battle {episode, ..} => *episode, - RoomMode::Challenge {episode, ..} => *episode, - } - } - - pub fn battle(&self) -> bool { - matches!(self, RoomMode::Battle {..}) - } - - pub fn challenge(&self) -> bool { - matches!(self, RoomMode::Challenge {..}) - } - - pub fn player_mode(&self) -> PlayerMode { - match self { - RoomMode::Single {..} => PlayerMode::Single, - _ => PlayerMode::Multi, - } - } -} pub enum QuestCategoryType { Standard, Government, @@ -369,7 +223,7 @@ impl RoomState { name: String, password: [u16; 16], event: ShipEvent, - map_builder: Arc Maps + Send + Sync>>, + map_builder: Arc) -> Maps + Send + Sync>>, drop_table_builder: Arc DropTable + Send + Sync>>, ) -> Result { let mode = match mode { @@ -397,7 +251,7 @@ impl RoomState { random_seed: rand::thread_rng().gen(), name, password, - maps: map_builder(mode, event), + maps: map_builder(mode, event.rare_enemy_event()), section_id, drop_table: Box::new(drop_table_builder(episode, difficulty, section_id)), bursting: false, diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 554d9d5..7e6293d 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -18,14 +18,16 @@ use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; use crate::common::interserver::{AuthToken, Ship, ServerId, InterserverActor, LoginMessage, ShipMessage}; use crate::login::character::SHIP_MENU_ID; -use crate::entity::gateway::{EntityGateway, GatewayError}; -use crate::entity::character::SectionID; -use crate::entity::room::RoomNote; +use entity::gateway::{EntityGateway, GatewayError}; +use entity::character::SectionID; +use entity::room::RoomNote; use crate::ship::location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; use crate::ship::drops::DropTable; use crate::ship::items; use crate::ship::room; -use crate::ship::map::{Maps, MapsError, MapAreaError, generate_free_roam_maps}; +use maps::area::MapAreaError; +use maps::maps::{Maps, MapsError, generate_free_roam_maps}; +use maps::enemy::RareEnemyEvent; use crate::ship::packet::handler; use crate::ship::shops::{WeaponShop, ToolShop, ArmorShop}; use crate::ship::trade::TradeState; @@ -38,57 +40,6 @@ pub const SHIP_PORT: u16 = 23423; pub const QUEST_CATEGORY_MENU_ID: u32 = 0xA2; pub const QUEST_SELECT_MENU_ID: u32 = 0xA3; -#[derive(Clone, Copy)] -pub enum ShipEvent { - None, - Christmas, - Valentines, - Easter, - Halloween, - Sonic, - NewYear, - Summer, - White, - Wedding, - Fall, - Spring, - Summer2, - Spring2, -} - -impl From for u32 { - fn from(other: ShipEvent) -> u32 { - u16::from(other) as u32 - } -} - -impl From for u16 { - fn from(other: ShipEvent) -> u16 { - u8::from(other) as u16 - } -} - -impl From for u8 { - fn from(other: ShipEvent) -> u8 { - match other { - ShipEvent::None => 0, - ShipEvent::Christmas => 1, - ShipEvent::Valentines => 3, - ShipEvent::Easter => 4, - ShipEvent::Halloween => 5, - ShipEvent::Sonic => 6, - ShipEvent::NewYear => 7, - ShipEvent::Summer => 8, - ShipEvent::White => 9, - ShipEvent::Wedding => 10, - ShipEvent::Fall => 11, - ShipEvent::Spring => 12, - ShipEvent::Summer2 => 13, - ShipEvent::Spring2 => 14, - } - } -} - #[derive(Error, Debug)] pub enum ShipError { @@ -139,7 +90,7 @@ pub enum ShipError { #[error("gateway error {0}")] GatewayError(#[from] GatewayError), #[error("unknown monster {0}")] - UnknownMonster(crate::ship::monster::MonsterType), + UnknownMonster(maps::monster::MonsterType), #[error("invalid ship {0}")] InvalidShip(usize), #[error("invalid block {0}")] @@ -166,6 +117,70 @@ impl> From for ShipError { } */ +#[derive(Clone, Copy)] +pub enum ShipEvent { + None, + Christmas, + Valentines, + Easter, + Halloween, + Sonic, + NewYear, + Summer, + White, + Wedding, + Fall, + Spring, + Summer2, + Spring2, +} + + +impl From for u32 { + fn from(other: ShipEvent) -> u32 { + u16::from(other) as u32 + } +} + +impl From for u16 { + fn from(other: ShipEvent) -> u16 { + u8::from(other) as u16 + } +} + +impl From for u8 { + fn from(other: ShipEvent) -> u8 { + match other { + ShipEvent::None => 0, + ShipEvent::Christmas => 1, + ShipEvent::Valentines => 3, + ShipEvent::Easter => 4, + ShipEvent::Halloween => 5, + ShipEvent::Sonic => 6, + ShipEvent::NewYear => 7, + ShipEvent::Summer => 8, + ShipEvent::White => 9, + ShipEvent::Wedding => 10, + ShipEvent::Fall => 11, + ShipEvent::Spring => 12, + ShipEvent::Summer2 => 13, + ShipEvent::Spring2 => 14, + } + } +} + +impl ShipEvent { + pub fn rare_enemy_event(&self) -> Option { + match self { + ShipEvent::Easter => Some(RareEnemyEvent::Easter), + ShipEvent::Halloween => Some(RareEnemyEvent::Halloween), + ShipEvent::Christmas => Some(RareEnemyEvent::Christmas), + _ => None, + } + } +} + + #[derive(Debug)] pub enum RecvShipPacket { @@ -345,14 +360,14 @@ impl SendServerPacket for SendShipPacket { #[derive(Clone)] pub struct ItemShops { - pub weapon_shop: HashMap<(room::Difficulty, SectionID), Arc>>>, + pub weapon_shop: HashMap<(maps::room::Difficulty, SectionID), Arc>>>, pub tool_shop: Arc>>, pub armor_shop: Arc>>, } impl Default for ItemShops { fn default() -> ItemShops { - let difficulty = [room::Difficulty::Normal, room::Difficulty::Hard, room::Difficulty::VeryHard, room::Difficulty::Ultimate]; + let difficulty = [maps::room::Difficulty::Normal, maps::room::Difficulty::Hard, maps::room::Difficulty::VeryHard, maps::room::Difficulty::Ultimate]; let section_id = [SectionID::Viridia, SectionID::Greenill, SectionID::Skyly, SectionID::Bluefull, SectionID::Purplenum, SectionID::Pinkal, SectionID::Redria, SectionID::Oran, SectionID::Yellowboze, SectionID::Whitill]; @@ -379,8 +394,8 @@ pub struct ShipServerStateBuilder { port: Option, auth_token: Option, event: Option, - map_builder: Option Maps + Send + Sync>>, - drop_table_builder: Option DropTable + Send + Sync>>, + map_builder: Option) -> Maps + Send + Sync>>, + drop_table_builder: Option DropTable + Send + Sync>>, num_blocks: usize, } @@ -438,13 +453,13 @@ impl ShipServerStateBuilder { } #[must_use] - pub fn map_builder(mut self, map_builder: Box Maps + Send + Sync>) -> ShipServerStateBuilder { + pub fn map_builder(mut self, map_builder: Box) -> Maps + Send + Sync>) -> ShipServerStateBuilder { self.map_builder = Some(map_builder); self } #[must_use] - pub fn drop_table_builder(mut self, drop_table_builder: Box DropTable + Send + Sync>) -> ShipServerStateBuilder { + pub fn drop_table_builder(mut self, drop_table_builder: Box DropTable + Send + Sync>) -> ShipServerStateBuilder { self.drop_table_builder = Some(drop_table_builder); self } @@ -516,8 +531,8 @@ pub struct ShipServerState { ship_list: Arc>>, shipgate_sender: Option>, trades: TradeState, - map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, + map_builder: Arc) -> Maps + Send + Sync>>, + drop_table_builder: Arc DropTable + Send + Sync>>, } impl ShipServerState { diff --git a/src/ship/shops/armor.rs b/src/ship/shops/armor.rs index d1d8b47..23fca20 100644 --- a/src/ship/shops/armor.rs +++ b/src/ship/shops/armor.rs @@ -5,10 +5,10 @@ use std::convert::TryInto; use serde::Deserialize; use rand::{Rng, SeedableRng}; use rand::distributions::{WeightedIndex, Distribution}; -use crate::entity::item::ItemDetail; -use crate::entity::item::armor::{Armor, ArmorType}; -use crate::entity::item::shield::{Shield, ShieldType}; -use crate::entity::item::unit::{Unit, UnitType}; +use entity::item::ItemDetail; +use entity::item::armor::{Armor, ArmorType}; +use entity::item::shield::{Shield, ShieldType}; +use entity::item::unit::{Unit, UnitType}; use crate::ship::shops::ShopItem; use crate::ship::item_stats::{ARMOR_STATS, SHIELD_STATS, UNIT_STATS}; diff --git a/src/ship/shops/mod.rs b/src/ship/shops/mod.rs index 573b667..7a999b7 100644 --- a/src/ship/shops/mod.rs +++ b/src/ship/shops/mod.rs @@ -2,7 +2,7 @@ mod weapon; mod tool; mod armor; -use crate::entity::item::ItemDetail; +use entity::item::ItemDetail; pub trait ShopItem { fn price(&self) -> usize; diff --git a/src/ship/shops/tool.rs b/src/ship/shops/tool.rs index b5f9718..73a44c7 100644 --- a/src/ship/shops/tool.rs +++ b/src/ship/shops/tool.rs @@ -6,9 +6,9 @@ use std::convert::TryInto; use serde::Deserialize; use rand::{Rng, SeedableRng}; use rand::distributions::{WeightedIndex, Distribution}; -use crate::entity::item::ItemDetail; -use crate::entity::item::tool::{Tool, ToolType}; -use crate::entity::item::tech::{Technique, TechniqueDisk}; +use entity::item::ItemDetail; +use entity::item::tool::{Tool, ToolType}; +use entity::item::tech::{Technique, TechniqueDisk}; use crate::ship::shops::ShopItem; use crate::ship::item_stats::{TOOL_STATS, TECH_STATS}; diff --git a/src/ship/shops/weapon.rs b/src/ship/shops/weapon.rs index 14509c8..6174b5a 100644 --- a/src/ship/shops/weapon.rs +++ b/src/ship/shops/weapon.rs @@ -8,10 +8,10 @@ use serde::Deserialize; use rand::{Rng, SeedableRng}; use rand::distributions::{WeightedIndex, Distribution}; use rand::seq::{SliceRandom, IteratorRandom}; -use crate::entity::character::SectionID; -use crate::ship::room::Difficulty; -use crate::entity::item::ItemDetail; -use crate::entity::item::weapon::{Weapon, WeaponType, WeaponSpecial, Attribute, WeaponAttribute}; +use entity::character::SectionID; +use maps::room::Difficulty; +use entity::item::ItemDetail; +use entity::item::weapon::{Weapon, WeaponType, WeaponSpecial, Attribute, WeaponAttribute}; use crate::ship::shops::ShopItem; use crate::ship::item_stats::WEAPON_STATS; diff --git a/tests/common.rs b/tests/common.rs index e9dccd0..6c8b577 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -1,14 +1,14 @@ #![allow(dead_code)] use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::EntityGateway; -use elseware::entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity}; -use elseware::entity::character::{CharacterEntity, NewCharacterEntity}; -use elseware::entity::item::{Meseta, BankName, BankIdentifier}; +use entity::gateway::EntityGateway; +use entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity}; +use entity::character::{CharacterEntity, NewCharacterEntity}; +use entity::item::{Meseta, BankName, BankIdentifier}; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; -use elseware::ship::room::Difficulty; +use maps::room::Difficulty; -use elseware::entity::item; +use entity::item; use libpso::packet::ship::*; use libpso::packet::login::{Login, Session}; diff --git a/tests/test_bank.rs b/tests/test_bank.rs index 71fc8f5..227e043 100644 --- a/tests/test_bank.rs +++ b/tests/test_bank.rs @@ -1,7 +1,7 @@ use std::collections::BTreeSet; use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::entity::item; +use entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; use libpso::packet::ship::*; diff --git a/tests/test_character.rs b/tests/test_character.rs index ca16eac..9ea3c93 100644 --- a/tests/test_character.rs +++ b/tests/test_character.rs @@ -1,5 +1,5 @@ use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::gateway::{EntityGateway, InMemoryGateway}; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; use libpso::character::settings::{DEFAULT_KEYBOARD_CONFIG1, DEFAULT_KEYBOARD_CONFIG2, DEFAULT_KEYBOARD_CONFIG3, DEFAULT_KEYBOARD_CONFIG4}; diff --git a/tests/test_exp_gain.rs b/tests/test_exp_gain.rs index 0317e9d..6cecb60 100644 --- a/tests/test_exp_gain.rs +++ b/tests/test_exp_gain.rs @@ -1,13 +1,13 @@ use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::gateway::{EntityGateway, InMemoryGateway}; use elseware::common::leveltable::CharacterLevelTable; use elseware::ship::ship::{ShipServerState, SendShipPacket, RecvShipPacket}; -use elseware::ship::monster::MonsterType; use elseware::ship::location::RoomId; -use elseware::ship::map::variant::{MapVariant, MapVariantMode}; -use elseware::ship::map::maps::Maps; -use elseware::ship::map::area::MapArea; -use elseware::ship::map::enemy::MapEnemy; +use maps::variant::{MapVariant, MapVariantMode}; +use maps::maps::Maps; +use maps::area::MapArea; +use maps::enemy::MapEnemy; +use maps::monster::MonsterType; use libpso::packet::ship::*; use libpso::packet::messages::*; diff --git a/tests/test_item_actions.rs b/tests/test_item_actions.rs index 77d52bc..d840cab 100644 --- a/tests/test_item_actions.rs +++ b/tests/test_item_actions.rs @@ -1,7 +1,7 @@ use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::gateway::{EntityGateway, InMemoryGateway}; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; -use elseware::entity::item; +use entity::item; use libpso::packet::ship::*; use libpso::packet::messages::*; diff --git a/tests/test_item_drop.rs b/tests/test_item_drop.rs index 02b01b1..3f2f55a 100644 --- a/tests/test_item_drop.rs +++ b/tests/test_item_drop.rs @@ -1,15 +1,18 @@ use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::entity::character::SectionID; +use entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::character::SectionID; use elseware::common::leveltable::CharacterLevelTable; use elseware::ship::ship::{ShipServerState, SendShipPacket, RecvShipPacket}; -use elseware::ship::room::{Episode, Difficulty}; -use elseware::ship::monster::MonsterType; +use maps::room::{Episode, Difficulty}; +use maps::monster::MonsterType; use elseware::ship::location::RoomId; use elseware::ship::drops::{DropTable, MonsterDropStats, MonsterDropType}; use elseware::ship::drops::rare_drop_table::{RareDropTable, RareDropRate, RareDropItem}; -use elseware::ship::map::{Maps, MapVariant, MapArea, MapVariantMode, MapEnemy}; -use elseware::entity::item::weapon::WeaponType; +use maps::maps::Maps; +use maps::area::MapArea; +use maps::variant::{MapVariant, MapVariantMode}; +use maps::enemy::MapEnemy; +use entity::item::weapon::WeaponType; use libpso::packet::ship::*; use libpso::packet::messages::*; diff --git a/tests/test_item_id.rs b/tests/test_item_id.rs index f8ba644..0d8d70e 100644 --- a/tests/test_item_id.rs +++ b/tests/test_item_id.rs @@ -1,8 +1,8 @@ use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::entity::item; +use entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; -use elseware::entity::character::TechLevel; +use entity::character::TechLevel; //use elseware::ship::items::{ClientItemId, ActiveItemEntityId, HeldItemType, FloorItemType}; use libpso::packet::ship::*; diff --git a/tests/test_item_pickup.rs b/tests/test_item_pickup.rs index 394cc3a..ca1b118 100644 --- a/tests/test_item_pickup.rs +++ b/tests/test_item_pickup.rs @@ -1,6 +1,6 @@ use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::entity::item; +use entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; use libpso::packet::ship::*; diff --git a/tests/test_item_use.rs b/tests/test_item_use.rs index b6b8502..fab748b 100644 --- a/tests/test_item_use.rs +++ b/tests/test_item_use.rs @@ -1,8 +1,8 @@ use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::entity::item; +use entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; -use elseware::entity::character::TechLevel; +use entity::character::TechLevel; //use elseware::ship::items::{ClientItemId, ActiveItemEntityId, HeldItemType, FloorItemType}; use libpso::packet::ship::*; diff --git a/tests/test_mags.rs b/tests/test_mags.rs index 1a7d687..fe098d9 100644 --- a/tests/test_mags.rs +++ b/tests/test_mags.rs @@ -1,8 +1,8 @@ use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::entity::item; +use entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; -use elseware::entity::character::{CharacterClass, SectionID}; +use entity::character::{CharacterClass, SectionID}; use libpso::packet::ship::*; use libpso::packet::messages::*; diff --git a/tests/test_rooms.rs b/tests/test_rooms.rs index 00b512d..73c2a77 100644 --- a/tests/test_rooms.rs +++ b/tests/test_rooms.rs @@ -1,6 +1,6 @@ use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::entity::item; +use entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; use elseware::ship::location::RoomId; diff --git a/tests/test_shops.rs b/tests/test_shops.rs index cf230c9..6a94a04 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -1,8 +1,8 @@ use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::entity::item; +use entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket, ShipError}; -use elseware::ship::room::Difficulty; +use maps::room::Difficulty; use elseware::ship::items::state::ItemStateError; use libpso::packet::ship::*; diff --git a/tests/test_trade.rs b/tests/test_trade.rs index 4155a46..a895ed4 100644 --- a/tests/test_trade.rs +++ b/tests/test_trade.rs @@ -1,9 +1,9 @@ use std::convert::TryInto; use elseware::common::serverstate::{ClientId, ServerState}; -use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::entity::item; +use entity::gateway::{EntityGateway, InMemoryGateway}; +use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket, ShipError}; -use elseware::entity::item::{Meseta, ItemEntity}; +use entity::item::{Meseta, ItemEntity, InventoryItemEntity}; use elseware::ship::packet::handler::trade::TradeError; use libpso::packet::ship::*; @@ -62,7 +62,7 @@ struct TradeItemBuilder { } impl TradeItemBuilder { - fn individual(mut self, item: &elseware::entity::item::InventoryItemEntity, item_id: u32) -> Self { + fn individual(mut self, item: &InventoryItemEntity, item_id: u32) -> Self { let idata = item.with_individual(|i| i.item.as_client_bytes()).unwrap(); self.items[self.count] = TradeItem { item_data: idata[0..12].try_into().unwrap(), @@ -74,7 +74,7 @@ impl TradeItemBuilder { self } - fn stacked(mut self, item: &elseware::entity::item::InventoryItemEntity, item_id: u32, amount: u8) -> Self { + fn stacked(mut self, item: &InventoryItemEntity, item_id: u32, amount: u8) -> Self { let idata = item .with_stacked(|i| i[0].item.tool().unwrap().as_stacked_bytes(i.len())) .map(|mut data| { -- 2.36.0 From 37ff01a186ff0ade53cadcc2d5e931b3892331de Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 10 Nov 2023 22:04:20 -0700 Subject: [PATCH 21/58] genuflect towards the great clippy --- maps/src/enemy.rs | 2 +- src/bin/patch.rs | 4 +--- src/common/mainloop/interserver.rs | 8 ++------ src/ship/drops/box_drop_table.rs | 5 ++--- src/ship/drops/generic_armor.rs | 8 ++++---- src/ship/drops/generic_shield.rs | 4 ++-- src/ship/drops/generic_weapon.rs | 6 +++--- src/ship/items/apply_item.rs | 2 +- src/ship/items/bank.rs | 12 ++---------- src/ship/packet/builder/room.rs | 1 + src/ship/shops/armor.rs | 4 ++-- src/ship/shops/tool.rs | 13 ++----------- src/ship/shops/weapon.rs | 4 ++-- 13 files changed, 25 insertions(+), 48 deletions(-) diff --git a/maps/src/enemy.rs b/maps/src/enemy.rs index 08e0f61..033b05d 100644 --- a/maps/src/enemy.rs +++ b/maps/src/enemy.rs @@ -81,7 +81,7 @@ pub fn load_rare_monster_file(episode: Episode) let mut f = File::open(path).unwrap(); let mut s = String::new(); - f.read_to_string(&mut s); + f.read_to_string(&mut s).unwrap(); toml::from_str::(s.as_str()).unwrap() } diff --git a/src/bin/patch.rs b/src/bin/patch.rs index e7304d8..6716391 100644 --- a/src/bin/patch.rs +++ b/src/bin/patch.rs @@ -12,7 +12,5 @@ fn main() { elseware::common::mainloop::run_server(patch_state, patch_config.port).await; }); - async_std::task::block_on(async move { - patch_loop.await - }); + async_std::task::block_on(patch_loop); } diff --git a/src/common/mainloop/interserver.rs b/src/common/mainloop/interserver.rs index d524952..0465f43 100644 --- a/src/common/mainloop/interserver.rs +++ b/src/common/mainloop/interserver.rs @@ -219,12 +219,8 @@ where let mut buf = [0u8; 1]; loop { let peek = socket.peek(&mut buf).await; - match peek { - Ok(len) if len == 0 => { - break - }, - _ => { - } + if let Ok(0) = peek { + break } } } diff --git a/src/ship/drops/box_drop_table.rs b/src/ship/drops/box_drop_table.rs index 4ad1e60..e5e6f8d 100644 --- a/src/ship/drops/box_drop_table.rs +++ b/src/ship/drops/box_drop_table.rs @@ -13,7 +13,6 @@ use crate::ship::drops::generic_armor::GenericArmorTable; use crate::ship::drops::generic_shield::GenericShieldTable; use crate::ship::drops::generic_unit::GenericUnitTable; use crate::ship::drops::tool_table::ToolTable; -use entity::item::ItemDetail; #[derive(Debug, Serialize, Deserialize)] struct BoxDropRate { @@ -176,8 +175,8 @@ impl BoxDropTable { fn random_box_drop(&self, map_area: &MapArea, rng: &mut R) -> Option { self.rare_drop(map_area, rng).or_else(|| { let rate = self.box_rates.rates_by_area(map_area); - let type_weights = WeightedIndex::new(&[rate.weapon_rate, rate.armor_rate, rate.shield_rate, rate.unit_rate, - rate.tool_rate, rate.meseta_rate, rate.nothing_rate]).unwrap(); + let type_weights = WeightedIndex::new([rate.weapon_rate, rate.armor_rate, rate.shield_rate, rate.unit_rate, + rate.tool_rate, rate.meseta_rate, rate.nothing_rate]).unwrap(); let btype = type_weights.sample(rng); match btype { 0 => self.weapon_table.get_drop(map_area, rng), diff --git a/src/ship/drops/generic_armor.rs b/src/ship/drops/generic_armor.rs index 80e4761..6c70934 100644 --- a/src/ship/drops/generic_armor.rs +++ b/src/ship/drops/generic_armor.rs @@ -46,8 +46,8 @@ impl GenericArmorTable { } fn armor_type(&self, area_map: &MapArea, rng: &mut R) -> ArmorType { - let rank_weights = WeightedIndex::new(&[self.rank_rates.rank0, self.rank_rates.rank1, self.rank_rates.rank2, - self.rank_rates.rank3, self.rank_rates.rank4]).unwrap(); + let rank_weights = WeightedIndex::new([self.rank_rates.rank0, self.rank_rates.rank1, self.rank_rates.rank2, + self.rank_rates.rank3, self.rank_rates.rank4]).unwrap(); let rank = rank_weights.sample(rng) as i32; let armor_level = std::cmp::max(0i32, self.armor_set as i32 - 3i32 + rank + area_map.drop_area_value().unwrap_or(0) as i32); match armor_level { @@ -80,8 +80,8 @@ impl GenericArmorTable { } pub fn slots(&self, _area_map: &MapArea, rng: &mut R) -> usize { - let slot_weights = WeightedIndex::new(&[self.slot_rates.slot0, self.slot_rates.slot1, self.slot_rates.slot2, - self.slot_rates.slot3, self.slot_rates.slot4]).unwrap(); + let slot_weights = WeightedIndex::new([self.slot_rates.slot0, self.slot_rates.slot1, self.slot_rates.slot2, + self.slot_rates.slot3, self.slot_rates.slot4]).unwrap(); slot_weights.sample(rng) } diff --git a/src/ship/drops/generic_shield.rs b/src/ship/drops/generic_shield.rs index fd5752e..3ca20c9 100644 --- a/src/ship/drops/generic_shield.rs +++ b/src/ship/drops/generic_shield.rs @@ -36,8 +36,8 @@ impl GenericShieldTable { } fn shield_type(&self, area_map: &MapArea, rng: &mut R) -> ShieldType { - let rank_weights = WeightedIndex::new(&[self.rank_rates.rank0, self.rank_rates.rank1, self.rank_rates.rank2, - self.rank_rates.rank3, self.rank_rates.rank4]).unwrap(); + let rank_weights = WeightedIndex::new([self.rank_rates.rank0, self.rank_rates.rank1, self.rank_rates.rank2, + self.rank_rates.rank3, self.rank_rates.rank4]).unwrap(); let rank = rank_weights.sample(rng) as i32; let shield_level = std::cmp::max(0i32, self.shield_set as i32 - 3i32 + rank + area_map.drop_area_value().unwrap_or(0) as i32); match shield_level { diff --git a/src/ship/drops/generic_weapon.rs b/src/ship/drops/generic_weapon.rs index 38290e7..0872c8e 100644 --- a/src/ship/drops/generic_weapon.rs +++ b/src/ship/drops/generic_weapon.rs @@ -240,7 +240,7 @@ impl AttributeTable { fn generate_attribute(&self, pattern: &PercentPatternType, rates: &AttributeRate, rng: &mut R) -> Option { - let attribute_weights = WeightedIndex::new(&[rates.none, rates.native, rates.abeast, rates.machine, rates.dark, rates.hit]).unwrap(); + let attribute_weights = WeightedIndex::new([rates.none, rates.native, rates.abeast, rates.machine, rates.dark, rates.hit]).unwrap(); let attr = match attribute_weights.sample(rng) { 0 => return None, 1 => Attribute::Native, @@ -253,7 +253,7 @@ impl AttributeTable { let percents = self.percent_rates.get_by_pattern(pattern); - let value_weights = WeightedIndex::new(&percents.as_array()).unwrap(); + let value_weights = WeightedIndex::new(percents.as_array()).unwrap(); let value = value_weights.sample(rng); let percent = ((value + 1) * 5) as i8; @@ -477,7 +477,7 @@ impl GenericWeaponTable { let pattern = std::cmp::min(area % ratio.inc, 3); let weights = self.grind_rates.grind_rate[pattern as usize]; - let grind_choice = WeightedIndex::new(&weights).unwrap(); + let grind_choice = WeightedIndex::new(weights).unwrap(); grind_choice.sample(rng) } diff --git a/src/ship/items/apply_item.rs b/src/ship/items/apply_item.rs index 9c7e3c2..ef0e05f 100644 --- a/src/ship/items/apply_item.rs +++ b/src/ship/items/apply_item.rs @@ -226,7 +226,7 @@ pub async fn liberta_kit(entity_gateway: &mut EG, used_cell: fn jack_o_lantern() -> Result, anyhow::Error> { - let mag_rate = WeightedIndex::new(&[13, 13, 13, 13, 12, 12, 12, 12]).unwrap(); + let mag_rate = WeightedIndex::new([13, 13, 13, 13, 12, 12, 12, 12]).unwrap(); let mag_type = match mag_rate.sample(&mut rand_chacha::ChaChaRng::from_entropy()) { 0 => ToolType::CellOfMag502, 1 => ToolType::CellOfMag213, diff --git a/src/ship/items/bank.rs b/src/ship/items/bank.rs index f6d12cd..799cb03 100644 --- a/src/ship/items/bank.rs +++ b/src/ship/items/bank.rs @@ -325,15 +325,7 @@ impl std::cmp::Eq for BankItemDetail {} impl std::cmp::PartialOrd for BankItemDetail { fn partial_cmp(&self, other: &BankItemDetail) -> Option { - let mut self_bytes = [0u8; 4]; - let mut other_bytes = [0u8; 4]; - self_bytes.copy_from_slice(&self.as_client_bytes()[0..4]); - other_bytes.copy_from_slice(&other.as_client_bytes()[0..4]); - - let self_value = u32::from_be_bytes(self_bytes); - let other_value = u32::from_be_bytes(other_bytes); - - self_value.partial_cmp(&other_value) + Some(self.cmp(other)) } } @@ -362,7 +354,7 @@ impl std::cmp::Eq for BankItem {} impl std::cmp::PartialOrd for BankItem { fn partial_cmp(&self, other: &BankItem) -> Option { - self.item.partial_cmp(&other.item) + Some(self.cmp(other)) } } diff --git a/src/ship/packet/builder/room.rs b/src/ship/packet/builder/room.rs index 2b5c8e5..1f922a1 100644 --- a/src/ship/packet/builder/room.rs +++ b/src/ship/packet/builder/room.rs @@ -17,6 +17,7 @@ pub async fn join_room(id: ClientId, event: ShipEvent) -> Result { let all_clients = client_location.get_clients_in_room(room_id).await.map_err(|err| -> ClientLocationError { err.into() })?; + #[allow(clippy::manual_try_fold)] // I don't think its even possible to make this work here let players = futures::stream::iter(all_clients.iter()) .enumerate() .fold::, _, _>(Ok([PlayerHeader::default(); 4]), |acc, (i, c)| async move { diff --git a/src/ship/shops/armor.rs b/src/ship/shops/armor.rs index 23fca20..557856e 100644 --- a/src/ship/shops/armor.rs +++ b/src/ship/shops/armor.rs @@ -342,8 +342,8 @@ impl ArmorShop { pub fn generate_armor_list(&mut self, character_level: usize) -> Vec { self.generate_frame_list(character_level).into_iter() - .chain(self.generate_barrier_list(character_level).into_iter()) - .chain(self.generate_unit_list(character_level).into_iter()) + .chain(self.generate_barrier_list(character_level)) + .chain(self.generate_unit_list(character_level)) .collect() } } diff --git a/src/ship/shops/tool.rs b/src/ship/shops/tool.rs index 73a44c7..9691456 100644 --- a/src/ship/shops/tool.rs +++ b/src/ship/shops/tool.rs @@ -36,16 +36,7 @@ impl Ord for ToolShopItem { impl PartialOrd for ToolShopItem { fn partial_cmp(&self, other: &ToolShopItem) -> Option { - let a = match self { - ToolShopItem::Tool(t) => Tool{tool : *t}.as_individual_bytes(), - ToolShopItem::Tech(t) => t.as_bytes(), - }; - let b = match other { - ToolShopItem::Tool(t) => Tool{tool : *t}.as_individual_bytes(), - ToolShopItem::Tech(t) => t.as_bytes(), - }; - - a.partial_cmp(&b) + Some(self.cmp(other)) } } @@ -285,7 +276,7 @@ impl ToolShop { pub fn generate_tool_list(&mut self, character_level: usize) -> Vec { let mut tools = Vec::new().into_iter() .chain(self.tools.0.clone().into_iter().map(ToolShopItem::Tool)) - .chain(self.generate_techs(character_level).into_iter()) + .chain(self.generate_techs(character_level)) .collect::>(); tools.sort(); tools diff --git a/src/ship/shops/weapon.rs b/src/ship/shops/weapon.rs index 6174b5a..699b76a 100644 --- a/src/ship/shops/weapon.rs +++ b/src/ship/shops/weapon.rs @@ -412,7 +412,7 @@ impl WeaponShop { .last() .unwrap(); - let attr_choice = WeightedIndex::new(&[tier.none, tier.native, tier.abeast, tier.machine, tier.dark, tier.hit]).unwrap(); + let attr_choice = WeightedIndex::new([tier.none, tier.native, tier.abeast, tier.machine, tier.dark, tier.hit]).unwrap(); let attr = match attr_choice.sample(&mut self.rng) { 0 => return None, 1 => Attribute::Native, @@ -439,7 +439,7 @@ impl WeaponShop { .last() .unwrap(); - let attr_choice = WeightedIndex::new(&[tier.none, tier.native, tier.abeast, tier.machine, tier.dark, tier.hit]).unwrap(); + let attr_choice = WeightedIndex::new([tier.none, tier.native, tier.abeast, tier.machine, tier.dark, tier.hit]).unwrap(); let attr = match attr_choice.sample(&mut self.rng) { 0 => return None, 1 => Attribute::Native, -- 2.36.0 From c7d10eeacf7edf29cb3510761dc07630e5ed11d8 Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 10 Nov 2023 22:16:30 -0700 Subject: [PATCH 22/58] actually this shouldn't be needed --- Cargo.toml | 3 --- common/Cargo.toml | 8 -------- common/src/lib.rs | 0 maps/Cargo.toml | 1 - 4 files changed, 12 deletions(-) delete mode 100644 common/Cargo.toml delete mode 100644 common/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 7561e6b..3e3c47b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" members = [ "entity", "maps", - "common", "networking", ] @@ -16,7 +15,6 @@ members = [ libpso = { git = "http://git.sharnoth.com/jake/libpso" } entity = { path = "./entity" } maps = { path = "./maps" } -common = { path = "./common" } networking = { path = "./networking" } async-std = { version = "1.9.0", features = ["unstable", "attributes"] } futures = "0.3.5" @@ -50,7 +48,6 @@ anyhow = { version = "1.0.68", features = ["backtrace"] } libpso = { git = "http://git.sharnoth.com/jake/libpso" } entity = { path = "./entity" } maps = { path = "./maps" } -common = { path = "./common" } networking = { path = "./networking" } async-std = { version = "1.9.0", features = ["unstable", "attributes"] } futures = "0.3.5" diff --git a/common/Cargo.toml b/common/Cargo.toml deleted file mode 100644 index 552f659..0000000 --- a/common/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "common" -version = "0.1.0" -edition = "2021" - - -[dependencies] -derive_more = { workspace = true } \ No newline at end of file diff --git a/common/src/lib.rs b/common/src/lib.rs deleted file mode 100644 index e69de29..0000000 diff --git a/maps/Cargo.toml b/maps/Cargo.toml index cf0401e..db84b6a 100644 --- a/maps/Cargo.toml +++ b/maps/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -common = { workspace = true } byteorder = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } -- 2.36.0 From f7cf6cd349f5a6df7939660c2b60a8d7130b9ea8 Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 10 Nov 2023 22:17:27 -0700 Subject: [PATCH 23/58] cleanup --- entity/Cargo.toml | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/entity/Cargo.toml b/entity/Cargo.toml index 6603cbb..ce90e98 100644 --- a/entity/Cargo.toml +++ b/entity/Cargo.toml @@ -21,37 +21,3 @@ futures = { workspace = true } strum = { workspace = true } strum_macros = { workspace = true } toml = { workspace = true } - - -#libpso = { git = "http://git.sharnoth.com/jake/libpso" } -#async-std = { version = "1.9.0", features = ["unstable", "attributes"] } -#futures = "0.3.5" -#rand = "0.7.3" -#rand_chacha = "0.2.2" -#crc = "^1.0.0" -#bcrypt = "0.10" -#chrono = "0.4.11" -#serde = "*" -#serde_json = "*" -#ron = "*" -#toml = "*" -#log = "*" -#fern = { version = "0.5", features = ["colored"] } -#byteorder = "1" -#enum-utils = "0.1.2" -#derive_more = { version = "0.99.3", features = ["display"]} -#thiserror = "1.0.37" -#ages-prs = "0.1" -#async-trait = "0.1.51" -#async-recursion= "1.0.0" -#lazy_static = "1.4.0" -#barrel = { version = "0.6.5", features = ["pg"] } -#refinery = { version = "0.5.0", features = ["postgres"] } -#sqlx = { version = "0.6.2", features = ["runtime-async-std-native-tls", "postgres", "json", "chrono"] } -#strum = "0.19.5" -#strum_macros = "0.19" -#anyhow = { version = "1.0.68", features = ["backtrace"] } - -#[lib] -#name = "entity" -#path = "lib.rs" \ No newline at end of file -- 2.36.0 From 03507df187eec88fb3e8f3a0d4cf9d8e7412ca28 Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 10 Nov 2023 22:29:50 -0700 Subject: [PATCH 24/58] oh wow this has been wrong this entire time --- src/ship/items/bank.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ship/items/bank.rs b/src/ship/items/bank.rs index 799cb03..885aba4 100644 --- a/src/ship/items/bank.rs +++ b/src/ship/items/bank.rs @@ -336,8 +336,8 @@ impl std::cmp::Ord for BankItemDetail { self_bytes.copy_from_slice(&self.as_client_bytes()[0..4]); other_bytes.copy_from_slice(&other.as_client_bytes()[0..4]); - let self_value = u32::from_le_bytes(self_bytes); - let other_value = u32::from_le_bytes(other_bytes); + let self_value = u32::from_be_bytes(self_bytes); + let other_value = u32::from_be_bytes(other_bytes); self_value.cmp(&other_value) } -- 2.36.0 From 04e9aa91d89a4705f60cc58602e9023cbc16c560 Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 10 Nov 2023 23:17:37 -0700 Subject: [PATCH 25/58] maybe specifying only 1 test job at a time will keep it from running out of memory --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index ae267b5..fd5f76f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -33,7 +33,7 @@ steps: - name: target-cache path: /drone/src/target commands: - - cargo test + - cargo test --jobs 1 volumes: - name: cache -- 2.36.0 From 7020f38863b0f05ea9a972674cb3033d9ef3aad6 Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 10 Nov 2023 23:31:47 -0700 Subject: [PATCH 26/58] crates for shops and stats --- Cargo.toml | 6 ++++++ shops/Cargo.toml | 13 +++++++++++++ {src/ship/shops => shops/src}/armor.rs | 4 ++-- src/ship/shops/mod.rs => shops/src/lib.rs | 0 {src/ship/shops => shops/src}/tool.rs | 4 ++-- {src/ship/shops => shops/src}/weapon.rs | 4 ++-- src/ship/client.rs | 2 +- src/ship/drops/generic_armor.rs | 2 +- src/ship/drops/generic_shield.rs | 2 +- src/ship/drops/generic_unit.rs | 2 +- src/ship/items/actions.rs | 2 +- src/ship/items/inventory.rs | 2 +- src/ship/items/tasks.rs | 2 +- src/ship/mod.rs | 4 ++-- src/ship/packet/builder/message.rs | 2 +- src/ship/packet/handler/direct_message.rs | 2 +- src/ship/ship.rs | 2 +- stats/Cargo.toml | 10 ++++++++++ src/ship/item_stats.rs => stats/src/items.rs | 0 stats/src/lib.rs | 1 + 20 files changed, 48 insertions(+), 18 deletions(-) create mode 100644 shops/Cargo.toml rename {src/ship/shops => shops/src}/armor.rs (98%) rename src/ship/shops/mod.rs => shops/src/lib.rs (100%) rename {src/ship/shops => shops/src}/tool.rs (98%) rename {src/ship/shops => shops/src}/weapon.rs (99%) create mode 100644 stats/Cargo.toml rename src/ship/item_stats.rs => stats/src/items.rs (100%) create mode 100644 stats/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 3e3c47b..0ea2e3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,8 @@ members = [ "entity", "maps", "networking", + "shops", + "stats", ] [workspace.dependencies] @@ -16,6 +18,8 @@ libpso = { git = "http://git.sharnoth.com/jake/libpso" } entity = { path = "./entity" } maps = { path = "./maps" } networking = { path = "./networking" } +shops = { path = "./shops" } +stats = { path = "./stats" } async-std = { version = "1.9.0", features = ["unstable", "attributes"] } futures = "0.3.5" rand = "0.7.3" @@ -49,6 +53,8 @@ libpso = { git = "http://git.sharnoth.com/jake/libpso" } entity = { path = "./entity" } maps = { path = "./maps" } networking = { path = "./networking" } +shops = { path = "./shops" } +stats = { path = "./stats" } async-std = { version = "1.9.0", features = ["unstable", "attributes"] } futures = "0.3.5" rand = "0.7.3" diff --git a/shops/Cargo.toml b/shops/Cargo.toml new file mode 100644 index 0000000..495bf2f --- /dev/null +++ b/shops/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "shops" +version = "0.1.0" +edition = "2021" + +[dependencies] +maps = { workspace = true } +stats = { workspace = true } +entity = { workspace = true } + +rand = { workspace = true } +toml = { workspace = true } +serde = { workspace = true } \ No newline at end of file diff --git a/src/ship/shops/armor.rs b/shops/src/armor.rs similarity index 98% rename from src/ship/shops/armor.rs rename to shops/src/armor.rs index 557856e..f424877 100644 --- a/src/ship/shops/armor.rs +++ b/shops/src/armor.rs @@ -9,8 +9,8 @@ use entity::item::ItemDetail; use entity::item::armor::{Armor, ArmorType}; use entity::item::shield::{Shield, ShieldType}; use entity::item::unit::{Unit, UnitType}; -use crate::ship::shops::ShopItem; -use crate::ship::item_stats::{ARMOR_STATS, SHIELD_STATS, UNIT_STATS}; +use crate::ShopItem; +use stats::items::{ARMOR_STATS, SHIELD_STATS, UNIT_STATS}; // #[derive(Debug)] // pub enum ArmorShopItem { diff --git a/src/ship/shops/mod.rs b/shops/src/lib.rs similarity index 100% rename from src/ship/shops/mod.rs rename to shops/src/lib.rs diff --git a/src/ship/shops/tool.rs b/shops/src/tool.rs similarity index 98% rename from src/ship/shops/tool.rs rename to shops/src/tool.rs index 9691456..b068d19 100644 --- a/src/ship/shops/tool.rs +++ b/shops/src/tool.rs @@ -9,8 +9,8 @@ use rand::distributions::{WeightedIndex, Distribution}; use entity::item::ItemDetail; use entity::item::tool::{Tool, ToolType}; use entity::item::tech::{Technique, TechniqueDisk}; -use crate::ship::shops::ShopItem; -use crate::ship::item_stats::{TOOL_STATS, TECH_STATS}; +use crate::ShopItem; +use stats::items::{TOOL_STATS, TECH_STATS}; #[derive(Debug, PartialEq, Eq)] diff --git a/src/ship/shops/weapon.rs b/shops/src/weapon.rs similarity index 99% rename from src/ship/shops/weapon.rs rename to shops/src/weapon.rs index 699b76a..06a8c1e 100644 --- a/src/ship/shops/weapon.rs +++ b/shops/src/weapon.rs @@ -12,8 +12,8 @@ use entity::character::SectionID; use maps::room::Difficulty; use entity::item::ItemDetail; use entity::item::weapon::{Weapon, WeaponType, WeaponSpecial, Attribute, WeaponAttribute}; -use crate::ship::shops::ShopItem; -use crate::ship::item_stats::WEAPON_STATS; +use crate::ShopItem; +use stats::items::WEAPON_STATS; const TIER1_SPECIAL: [WeaponSpecial; 8] = [WeaponSpecial::Draw, WeaponSpecial::Heart, WeaponSpecial::Ice, WeaponSpecial::Bind, diff --git a/src/ship/client.rs b/src/ship/client.rs index 58f75f7..abdf6ea 100644 --- a/src/ship/client.rs +++ b/src/ship/client.rs @@ -14,7 +14,7 @@ use entity::item; use crate::ship::ship::ShipError; use crate::ship::items; use maps::area::MapArea; -use crate::ship::shops::{WeaponShopItem, ToolShopItem, ArmorShopItem}; +use shops::{WeaponShopItem, ToolShopItem, ArmorShopItem}; #[derive(Clone, Default)] diff --git a/src/ship/drops/generic_armor.rs b/src/ship/drops/generic_armor.rs index 6c70934..4fa2667 100644 --- a/src/ship/drops/generic_armor.rs +++ b/src/ship/drops/generic_armor.rs @@ -8,7 +8,7 @@ use entity::item::armor::{ArmorType, Armor}; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; use crate::ship::drops::{ItemDropType, load_data_file}; -use crate::ship::item_stats::{armor_stats, ArmorStats}; +use stats::items::{armor_stats, ArmorStats}; #[derive(Debug, Serialize, Deserialize)] diff --git a/src/ship/drops/generic_shield.rs b/src/ship/drops/generic_shield.rs index 3ca20c9..bed92a6 100644 --- a/src/ship/drops/generic_shield.rs +++ b/src/ship/drops/generic_shield.rs @@ -8,7 +8,7 @@ use entity::character::SectionID; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; use crate::ship::drops::{ItemDropType, load_data_file}; -use crate::ship::item_stats::{shield_stats, ShieldStats}; +use stats::items::{shield_stats, ShieldStats}; #[derive(Debug, Serialize, Deserialize)] diff --git a/src/ship/drops/generic_unit.rs b/src/ship/drops/generic_unit.rs index 137f7d0..a5e1da5 100644 --- a/src/ship/drops/generic_unit.rs +++ b/src/ship/drops/generic_unit.rs @@ -8,7 +8,7 @@ use entity::item::unit::{UnitType, Unit, UnitModifier}; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; use crate::ship::drops::{ItemDropType, load_data_file}; -use crate::ship::item_stats::{unit_stats, UnitStats}; +use stats::items::{unit_stats, UnitStats}; diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index 2359950..f5f93f0 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -21,7 +21,7 @@ use crate::ship::items::bank::{BankItem, BankItemDetail}; use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail}; use crate::ship::items::floor::{FloorItem, FloorItemDetail}; use crate::ship::items::apply_item::{apply_item, ApplyItemAction}; -use crate::ship::shops::ShopItem; +use shops::ShopItem; use crate::ship::drops::{ItemDrop, ItemDropType}; use crate::ship::packet::builder; use crate::ship::location::AreaClient; diff --git a/src/ship/items/inventory.rs b/src/ship/items/inventory.rs index ca0e51d..e30eb93 100644 --- a/src/ship/items/inventory.rs +++ b/src/ship/items/inventory.rs @@ -9,7 +9,7 @@ use entity::character::CharacterEntityId; use entity::item::tool::ToolType; use entity::item::mag::Mag; use entity::item::weapon::Weapon; -use crate::ship::shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem}; +use shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem}; use crate::ship::items::state::ItemStateError; use crate::ship::items::state::{IndividualItemDetail, StackedItemDetail, AddItemResult}; use crate::ship::items::floor::{FloorItem, FloorItemDetail}; diff --git a/src/ship/items/tasks.rs b/src/ship/items/tasks.rs index f224f4c..d4910a1 100644 --- a/src/ship/items/tasks.rs +++ b/src/ship/items/tasks.rs @@ -12,7 +12,7 @@ use crate::ship::items::state::{ItemState, ItemStateProxy, IndividualItemDetail} use crate::ship::items::itemstateaction::{ItemStateAction, ItemAction}; use crate::ship::items::inventory::InventoryItem; use crate::ship::items::floor::FloorItem; -use crate::ship::shops::ShopItem; +use shops::ShopItem; use crate::ship::trade::TradeItem; use crate::ship::location::AreaClient; use crate::ship::drops::ItemDrop; diff --git a/src/ship/mod.rs b/src/ship/mod.rs index 3978099..d769c38 100644 --- a/src/ship/mod.rs +++ b/src/ship/mod.rs @@ -5,12 +5,12 @@ pub mod character; pub mod client; pub mod room; pub mod items; -pub mod item_stats; +//pub mod item_stats; //pub mod map; //pub mod monster; pub mod drops; pub mod packet; pub mod quests; -pub mod shops; +//pub mod shops; pub mod trade; pub mod chatcommand; diff --git a/src/ship/packet/builder/message.rs b/src/ship/packet/builder/message.rs index f83ebbd..85bc90b 100644 --- a/src/ship/packet/builder/message.rs +++ b/src/ship/packet/builder/message.rs @@ -10,7 +10,7 @@ use crate::ship::items::bank::BankState; use crate::ship::items::floor::FloorItem; use crate::ship::location::AreaClient; use std::convert::TryInto; -use crate::ship::shops::ShopItem; +use shops::ShopItem; pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem) -> Result { diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index 0886f79..c43efc9 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/src/ship/packet/handler/direct_message.rs @@ -14,7 +14,7 @@ use entity::gateway::EntityGateway; use entity::item; use libpso::utf8_to_utf16_array; use crate::ship::packet::builder; -use crate::ship::shops::{ShopItem, ToolShopItem, ArmorShopItem}; +use shops::{ShopItem, ToolShopItem, ArmorShopItem}; use crate::ship::items::state::{ItemState, ItemStateError}; use crate::ship::items::floor::{FloorType, FloorItemDetail}; use crate::ship::items::actions::TriggerCreateItem; diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 7e6293d..a384555 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -29,7 +29,7 @@ use maps::area::MapAreaError; use maps::maps::{Maps, MapsError, generate_free_roam_maps}; use maps::enemy::RareEnemyEvent; use crate::ship::packet::handler; -use crate::ship::shops::{WeaponShop, ToolShop, ArmorShop}; +use shops::{WeaponShop, ToolShop, ArmorShop}; use crate::ship::trade::TradeState; use crate::ship::chatcommand; diff --git a/stats/Cargo.toml b/stats/Cargo.toml new file mode 100644 index 0000000..e1d5801 --- /dev/null +++ b/stats/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "stats" +version = "0.1.0" +edition = "2021" + +[dependencies] +entity = { workspace = true } +toml = { workspace = true } +serde = { workspace = true } +lazy_static = { workspace = true } diff --git a/src/ship/item_stats.rs b/stats/src/items.rs similarity index 100% rename from src/ship/item_stats.rs rename to stats/src/items.rs diff --git a/stats/src/lib.rs b/stats/src/lib.rs new file mode 100644 index 0000000..339b22d --- /dev/null +++ b/stats/src/lib.rs @@ -0,0 +1 @@ +pub mod items; -- 2.36.0 From a76bb8945c3c8139e62ea1ddb183e6b3489ff915 Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 10 Nov 2023 23:38:56 -0700 Subject: [PATCH 27/58] clean up toplevel cargo.toml a bit --- Cargo.toml | 64 ++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0ea2e3a..20c9340 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,12 +14,14 @@ members = [ ] [workspace.dependencies] -libpso = { git = "http://git.sharnoth.com/jake/libpso" } entity = { path = "./entity" } maps = { path = "./maps" } networking = { path = "./networking" } shops = { path = "./shops" } stats = { path = "./stats" } + +libpso = { git = "http://git.sharnoth.com/jake/libpso" } + async-std = { version = "1.9.0", features = ["unstable", "attributes"] } futures = "0.3.5" rand = "0.7.3" @@ -49,36 +51,32 @@ strum_macros = "0.19" anyhow = { version = "1.0.68", features = ["backtrace"] } [dependencies] -libpso = { git = "http://git.sharnoth.com/jake/libpso" } -entity = { path = "./entity" } -maps = { path = "./maps" } -networking = { path = "./networking" } -shops = { path = "./shops" } -stats = { path = "./stats" } -async-std = { version = "1.9.0", features = ["unstable", "attributes"] } -futures = "0.3.5" -rand = "0.7.3" -rand_chacha = "0.2.2" -crc = "^1.0.0" -bcrypt = "0.10" +entity = { workspace = true } +maps = { workspace = true } +networking = { workspace = true } +shops = { workspace = true } +stats = { workspace = true } + +libpso = { workspace = true } + +ages-prs = { workspace = true } +anyhow = { workspace = true } +async-recursion = { workspace = true } +async-std = { workspace = true } +async-trait = { workspace = true } +bcrypt = { workspace = true } +byteorder = { workspace = true } chrono = { workspace = true } -serde = "*" -serde_json = "*" -ron = "*" -toml = "*" -log = "*" -fern = { version = "0.5", features = ["colored"] } -byteorder = "1" -enum-utils = "0.1.2" -derive_more = { version = "0.99.3", features = ["display"]} -thiserror = "1.0.37" -ages-prs = "0.1" -async-trait = "0.1.51" -async-recursion= "1.0.0" -lazy_static = "1.4.0" -barrel = { version = "0.6.5", features = ["pg"] } -refinery = { version = "0.5.0", features = ["postgres"] } -#sqlx = { version = "0.6.2", features = ["runtime-async-std-native-tls", "postgres", "json", "chrono"] } -strum = "0.19.5" -strum_macros = "0.19" -anyhow = { workspace = true } \ No newline at end of file +crc = { workspace = true } +derive_more = { workspace = true } +enum-utils = { workspace = true } +fern = { workspace = true } +futures = { workspace = true } +log = { workspace = true } +rand = { workspace = true } +rand_chacha = { workspace = true } +ron = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +toml = { workspace = true } +thiserror = { workspace = true } \ No newline at end of file -- 2.36.0 From 210d51e957472ca008c9e20aaee6893341f62a9e Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 10 Nov 2023 23:48:06 -0700 Subject: [PATCH 28/58] move leveltable to stats crate --- src/common/mod.rs | 1 - src/login/character.rs | 2 +- src/ship/character.rs | 2 +- src/ship/packet/builder/message.rs | 2 +- src/ship/packet/builder/mod.rs | 2 +- src/ship/packet/handler/direct_message.rs | 2 +- src/ship/packet/handler/lobby.rs | 2 +- src/ship/packet/handler/message.rs | 2 +- src/ship/packet/handler/room.rs | 2 +- stats/Cargo.toml | 1 + {src/common => stats/src}/leveltable.rs | 0 stats/src/lib.rs | 3 +++ 12 files changed, 12 insertions(+), 9 deletions(-) rename {src/common => stats/src}/leveltable.rs (100%) diff --git a/src/common/mod.rs b/src/common/mod.rs index d02076e..c8adde9 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -1,7 +1,6 @@ pub mod cipherkeys; pub mod serverstate; pub mod mainloop; -pub mod leveltable; pub mod interserver; // https://www.reddit.com/r/rust/comments/33xhhu/how_to_create_an_array_of_structs_that_havent/ diff --git a/src/login/character.rs b/src/login/character.rs index 07969ef..ef74730 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -18,7 +18,7 @@ use entity::item; use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; use crate::common::interserver::{ServerId, InterserverActor, LoginMessage, ShipMessage, Ship}; -use crate::common::leveltable::LEVEL_TABLE; +use stats::leveltable::LEVEL_TABLE; use libpso::{utf8_to_array, utf8_to_utf16_array}; use entity::gateway::{EntityGateway, GatewayError}; diff --git a/src/ship/character.rs b/src/ship/character.rs index afe73c6..90ba63b 100644 --- a/src/ship/character.rs +++ b/src/ship/character.rs @@ -1,5 +1,5 @@ use libpso::character::character; -use crate::common::leveltable::CharacterStats; +use stats::leveltable::CharacterStats; use entity::character::CharacterEntity; //use crate::ship::items::{CharacterInventory, CharacterBank}; use crate::ship::items::bank::BankState; diff --git a/src/ship/packet/builder/message.rs b/src/ship/packet/builder/message.rs index 85bc90b..d420187 100644 --- a/src/ship/packet/builder/message.rs +++ b/src/ship/packet/builder/message.rs @@ -1,7 +1,7 @@ use libpso::packet::messages::*; use libpso::packet::ship::*; use entity::item; -use crate::common::leveltable::CharacterStats; +use stats::leveltable::CharacterStats; use crate::ship::ship::{ShipError}; use crate::ship::items::ClientItemId; use crate::ship::items::inventory::InventoryItem; diff --git a/src/ship/packet/builder/mod.rs b/src/ship/packet/builder/mod.rs index f74015e..4872aaa 100644 --- a/src/ship/packet/builder/mod.rs +++ b/src/ship/packet/builder/mod.rs @@ -6,7 +6,7 @@ pub mod ship; use libpso::character::character::Inventory; use libpso::packet::ship::{PlayerHeader, PlayerInfo}; -use crate::common::leveltable::LEVEL_TABLE; +use stats::leveltable::LEVEL_TABLE; use crate::ship::character::CharacterBytesBuilder; use crate::ship::ship::ClientState; use crate::ship::location::AreaClient; diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index c43efc9..dea6911 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/src/ship/packet/handler/direct_message.rs @@ -3,7 +3,7 @@ use rand::Rng; use rand::seq::SliceRandom; use libpso::packet::ship::*; use libpso::packet::messages::*; -use crate::common::leveltable::LEVEL_TABLE; +use stats::leveltable::LEVEL_TABLE; use crate::common::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, ShipError, Clients, ItemShops}; use crate::ship::location::ClientLocation; diff --git a/src/ship/packet/handler/lobby.rs b/src/ship/packet/handler/lobby.rs index ae95afb..d085cc6 100644 --- a/src/ship/packet/handler/lobby.rs +++ b/src/ship/packet/handler/lobby.rs @@ -1,6 +1,6 @@ use libpso::packet::ship::*; use crate::common::serverstate::ClientId; -use crate::common::leveltable::LEVEL_TABLE; +use stats::leveltable::LEVEL_TABLE; use crate::ship::ship::{SendShipPacket, ShipError, Clients, ShipEvent}; use crate::ship::room::Rooms; use crate::ship::character::{FullCharacterBytesBuilder}; diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index a46b90c..497f2d9 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -3,7 +3,7 @@ use libpso::packet::messages::*; use entity::gateway::EntityGateway; use entity::item::Meseta; use crate::common::serverstate::ClientId; -use crate::common::leveltable::LEVEL_TABLE; +use stats::leveltable::LEVEL_TABLE; use crate::ship::ship::{SendShipPacket, ShipError, Clients, ItemDropLocation}; use crate::ship::room::Rooms; use crate::ship::location::{ClientLocation, ClientLocationError}; diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index cf5d6af..9fc8ccc 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -6,7 +6,7 @@ use async_std::sync::Arc; use libpso::packet::ship::*; use libpso::packet::messages::*; use crate::common::serverstate::ClientId; -use crate::common::leveltable::LEVEL_TABLE; +use stats::leveltable::LEVEL_TABLE; use entity::gateway::EntityGateway; use entity::character::SectionID; use entity::room::{NewRoomEntity, RoomEntityMode, RoomNote}; diff --git a/stats/Cargo.toml b/stats/Cargo.toml index e1d5801..6cebc62 100644 --- a/stats/Cargo.toml +++ b/stats/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" entity = { workspace = true } toml = { workspace = true } serde = { workspace = true } +serde_json = { workspace = true } lazy_static = { workspace = true } diff --git a/src/common/leveltable.rs b/stats/src/leveltable.rs similarity index 100% rename from src/common/leveltable.rs rename to stats/src/leveltable.rs diff --git a/stats/src/lib.rs b/stats/src/lib.rs index 339b22d..0564e34 100644 --- a/stats/src/lib.rs +++ b/stats/src/lib.rs @@ -1 +1,4 @@ +#![feature(lazy_cell)] + pub mod items; +pub mod leveltable; -- 2.36.0 From 8135d673ebf564fefe898ae222d4ea123ee37dc8 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 00:07:56 -0700 Subject: [PATCH 29/58] remove cargo cache for now, not enough disk space on my poverty ci vps --- .drone.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.drone.yml b/.drone.yml index fd5f76f..a8f5ce2 100644 --- a/.drone.yml +++ b/.drone.yml @@ -12,8 +12,6 @@ steps: volumes: - name: cache path: /usr/local/cargo - - name: target-cache - path: /drone/src/target commands: - cargo build - name: clippy! @@ -21,8 +19,6 @@ steps: volumes: - name: cache path: /usr/local/cargo - - name: target-cache - path: /drone/src/target commands: - cargo clippy -- --deny warnings - name: test @@ -30,8 +26,6 @@ steps: volumes: - name: cache path: /usr/local/cargo - - name: target-cache - path: /drone/src/target commands: - cargo test --jobs 1 -- 2.36.0 From cd1476796ef1ef3b400c9aa8ad444d388636aeee Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 14:28:41 -0700 Subject: [PATCH 30/58] break out the rest of everything into its own crate --- Cargo.toml | 24 ++ client/Cargo.toml | 20 ++ {src/ship => client/src}/client.rs | 18 +- client/src/lib.rs | 3 + drops/Cargo.toml | 17 ++ .../drops => drops/src}/box_drop_table.rs | 14 +- .../ship/drops => drops/src}/generic_armor.rs | 2 +- .../drops => drops/src}/generic_shield.rs | 2 +- {src/ship/drops => drops/src}/generic_unit.rs | 2 +- .../drops => drops/src}/generic_weapon.rs | 2 +- src/ship/drops/mod.rs => drops/src/lib.rs | 15 +- .../drops => drops/src}/rare_drop_table.rs | 8 +- {src/ship/drops => drops/src}/tech_table.rs | 2 +- {src/ship/drops => drops/src}/tool_table.rs | 4 +- items/Cargo.toml | 25 +++ {src/ship/items => items/src}/actions.rs | 36 +-- {src/ship/items => items/src}/apply_item.rs | 4 +- {src/ship/items => items/src}/bank.rs | 8 +- {src/ship/items => items/src}/floor.rs | 8 +- {src/ship/items => items/src}/inventory.rs | 8 +- .../items => items/src}/itemstateaction.rs | 0 src/ship/items/mod.rs => items/src/lib.rs | 3 + {src/ship/items => items/src}/manager.rs | 18 +- {src/ship/items => items/src}/state.rs | 14 +- {src/ship/items => items/src}/tasks.rs | 21 +- items/src/trade.rs | 38 ++++ location/Cargo.toml | 12 + location/src/lib.rs | 3 + {src/ship => location/src}/location.rs | 2 +- maps/src/enemy.rs | 18 +- maps/src/lib.rs | 52 +++++ maps/src/maps.rs | 7 +- networking/Cargo.toml | 14 ++ {src/common => networking/src}/cipherkeys.rs | 0 {src/common => networking/src}/interserver.rs | 0 networking/src/lib.rs | 18 ++ .../src}/mainloop/client.rs | 6 +- .../src}/mainloop/interserver.rs | 9 +- .../common => networking/src}/mainloop/mod.rs | 0 {src/common => networking/src}/serverstate.rs | 0 pktbuilder/Cargo.toml | 22 ++ {src/ship => pktbuilder/src}/character.rs | 5 +- .../builder/mod.rs => pktbuilder/src/lib.rs | 9 +- .../builder => pktbuilder/src}/lobby.rs | 15 +- .../builder => pktbuilder/src}/message.rs | 100 ++++----- .../builder => pktbuilder/src}/quest.rs | 5 +- .../packet/builder => pktbuilder/src}/room.rs | 21 +- .../packet/builder => pktbuilder/src}/ship.rs | 5 +- pktbuilder/src/team.rs | 107 +++++++++ .../builder => pktbuilder/src}/trade.rs | 0 quests/Cargo.toml | 18 ++ quests/src/lib.rs | 4 + {src/ship => quests/src}/quests.rs | 0 room/Cargo.toml | 17 ++ room/src/lib.rs | 3 + {src/ship => room/src}/room.rs | 33 +-- src/bin/login.rs | 8 +- src/bin/main.rs | 30 +-- src/bin/patch.rs | 4 +- src/bin/ship.rs | 8 +- src/common/mod.rs | 18 -- src/lib.rs | 3 +- src/login/character.rs | 11 +- src/login/login.rs | 4 +- src/patch/patch.rs | 4 +- src/ship/chatcommand.rs | 8 +- src/ship/drops/drop_table.rs | 0 src/ship/mod.rs | 16 +- src/ship/monster.rs | 212 ------------------ src/ship/packet/handler/auth.rs | 6 +- src/ship/packet/handler/communication.rs | 4 +- src/ship/packet/handler/direct_message.rs | 38 ++-- src/ship/packet/handler/lobby.rs | 30 +-- src/ship/packet/handler/message.rs | 30 ++- src/ship/packet/handler/quest.rs | 16 +- src/ship/packet/handler/room.rs | 23 +- src/ship/packet/handler/settings.rs | 2 +- src/ship/packet/handler/ship.rs | 6 +- src/ship/packet/handler/trade.rs | 28 +-- src/ship/packet/mod.rs | 2 +- src/ship/ship.rs | 105 ++------- tests/common.rs | 4 +- tests/test_bank.rs | 2 +- tests/test_character.rs | 2 +- tests/test_exp_gain.rs | 5 +- tests/test_item_actions.rs | 2 +- tests/test_item_drop.rs | 12 +- tests/test_item_id.rs | 4 +- tests/test_item_pickup.rs | 2 +- tests/test_item_use.rs | 3 +- tests/test_mags.rs | 2 +- tests/test_rooms.rs | 4 +- tests/test_shops.rs | 6 +- tests/test_trade.rs | 2 +- trade/Cargo.toml | 14 ++ trade/src/lib.rs | 4 + {src/ship => trade/src}/trade.rs | 42 +--- 97 files changed, 828 insertions(+), 719 deletions(-) create mode 100644 client/Cargo.toml rename {src/ship => client/src}/client.rs (93%) create mode 100644 client/src/lib.rs create mode 100644 drops/Cargo.toml rename {src/ship/drops => drops/src}/box_drop_table.rs (95%) rename {src/ship/drops => drops/src}/generic_armor.rs (98%) rename {src/ship/drops => drops/src}/generic_shield.rs (98%) rename {src/ship/drops => drops/src}/generic_unit.rs (98%) rename {src/ship/drops => drops/src}/generic_weapon.rs (99%) rename src/ship/drops/mod.rs => drops/src/lib.rs (96%) rename {src/ship/drops => drops/src}/rare_drop_table.rs (96%) rename {src/ship/drops => drops/src}/tech_table.rs (98%) rename {src/ship/drops => drops/src}/tool_table.rs (98%) create mode 100644 items/Cargo.toml rename {src/ship/items => items/src}/actions.rs (97%) rename {src/ship/items => items/src}/apply_item.rs (99%) rename {src/ship/items => items/src}/bank.rs (97%) rename {src/ship/items => items/src}/floor.rs (94%) rename {src/ship/items => items/src}/inventory.rs (98%) rename {src/ship/items => items/src}/itemstateaction.rs (100%) rename src/ship/items/mod.rs => items/src/lib.rs (87%) rename {src/ship/items => items/src}/manager.rs (99%) rename {src/ship/items => items/src}/state.rs (97%) rename {src/ship/items => items/src}/tasks.rs (97%) create mode 100644 items/src/trade.rs create mode 100644 location/Cargo.toml create mode 100644 location/src/lib.rs rename {src/ship => location/src}/location.rs (99%) rename {src/common => networking/src}/cipherkeys.rs (100%) rename {src/common => networking/src}/interserver.rs (100%) rename {src/common => networking/src}/mainloop/client.rs (97%) rename {src/common => networking/src}/mainloop/interserver.rs (95%) rename {src/common => networking/src}/mainloop/mod.rs (100%) rename {src/common => networking/src}/serverstate.rs (100%) create mode 100644 pktbuilder/Cargo.toml rename {src/ship => pktbuilder/src}/character.rs (98%) rename src/ship/packet/builder/mod.rs => pktbuilder/src/lib.rs (88%) rename {src/ship/packet/builder => pktbuilder/src}/lobby.rs (91%) rename {src/ship/packet/builder => pktbuilder/src}/message.rs (74%) rename {src/ship/packet/builder => pktbuilder/src}/quest.rs (94%) rename {src/ship/packet/builder => pktbuilder/src}/room.rs (85%) rename {src/ship/packet/builder => pktbuilder/src}/ship.rs (85%) create mode 100644 pktbuilder/src/team.rs rename {src/ship/packet/builder => pktbuilder/src}/trade.rs (100%) create mode 100644 quests/Cargo.toml create mode 100644 quests/src/lib.rs rename {src/ship => quests/src}/quests.rs (100%) create mode 100644 room/Cargo.toml create mode 100644 room/src/lib.rs rename {src/ship => room/src}/room.rs (90%) delete mode 100644 src/common/mod.rs delete mode 100644 src/ship/drops/drop_table.rs delete mode 100644 src/ship/monster.rs create mode 100644 trade/Cargo.toml create mode 100644 trade/src/lib.rs rename {src/ship => trade/src}/trade.rs (79%) diff --git a/Cargo.toml b/Cargo.toml index 20c9340..5737f97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,11 +6,19 @@ edition = "2021" [workspace] members = [ + "client", + "drops", "entity", + "items", + "location", "maps", "networking", + "pktbuilder", + "quests", + "room", "shops", "stats", + "trade", ] [workspace.dependencies] @@ -19,6 +27,14 @@ maps = { path = "./maps" } networking = { path = "./networking" } shops = { path = "./shops" } stats = { path = "./stats" } +items = { path = "./items" } +pktbuilder = { path = "./pktbuilder" } +quests = { path = "./quests" } +location = { path = "./location" } +client = { path = "./client" } +drops = { path = "./drops" } +trade = { path = "./trade" } +room = { path = "./room" } libpso = { git = "http://git.sharnoth.com/jake/libpso" } @@ -56,6 +72,14 @@ maps = { workspace = true } networking = { workspace = true } shops = { workspace = true } stats = { workspace = true } +items = { workspace = true } +pktbuilder = { workspace = true } +quests = { workspace = true } +location = { workspace = true } +client = { workspace = true } +drops = { workspace = true } +trade = { workspace = true } +room = { workspace = true } libpso = { workspace = true } diff --git a/client/Cargo.toml b/client/Cargo.toml new file mode 100644 index 0000000..12f9698 --- /dev/null +++ b/client/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "client" +version = "0.1.0" +edition = "2021" + + +[dependencies] +entity = { workspace = true } +maps = { workspace = true } +networking = { workspace = true } +shops = { workspace = true } +items = { workspace = true } + +libpso = { workspace = true } + +async-std = { workspace = true } +futures = { workspace = true } +anyhow = { workspace = true } +thiserror = { workspace = true } +chrono = { workspace = true } diff --git a/src/ship/client.rs b/client/src/client.rs similarity index 93% rename from src/ship/client.rs rename to client/src/client.rs index abdf6ea..21b2281 100644 --- a/src/ship/client.rs +++ b/client/src/client.rs @@ -6,17 +6,23 @@ use futures::future::BoxFuture; use libpso::packet::ship::*; use libpso::packet::login::Session; -use crate::common::serverstate::ClientId; +use networking::serverstate::ClientId; use entity::account::{UserAccountEntity, UserSettingsEntity}; use entity::character::CharacterEntity; use entity::item; -use crate::ship::ship::ShipError; -use crate::ship::items; +use items; use maps::area::MapArea; use shops::{WeaponShopItem, ToolShopItem, ArmorShopItem}; +#[derive(thiserror::Error, Debug)] +pub enum ClientError { + #[error("not found {0}")] + NotFound(ClientId), +} + + #[derive(Clone, Default)] pub struct Clients(Arc>>>); @@ -46,7 +52,7 @@ impl Clients { .await; let client = clients .get(&client_id) - .ok_or_else(|| ShipError::ClientNotFound(client_id))? + .ok_or_else(|| ClientError::NotFound(client_id))? .read() .await; @@ -69,7 +75,7 @@ impl Clients { for (cindex, client_id) in client_ids.iter().enumerate() { let c = clients .get(client_id) - .ok_or_else(|| ShipError::ClientNotFound(*client_id))? + .ok_or_else(|| ClientError::NotFound(*client_id))? .read() .await; client_states[cindex].write(c); @@ -95,7 +101,7 @@ impl Clients { .await; let mut client = clients .get(&client_id) - .ok_or_else(|| ShipError::ClientNotFound(client_id))? + .ok_or_else(|| ClientError::NotFound(client_id))? .write() .await; diff --git a/client/src/lib.rs b/client/src/lib.rs new file mode 100644 index 0000000..c8ab57b --- /dev/null +++ b/client/src/lib.rs @@ -0,0 +1,3 @@ +pub mod client; + +pub use client::*; diff --git a/drops/Cargo.toml b/drops/Cargo.toml new file mode 100644 index 0000000..199e7c6 --- /dev/null +++ b/drops/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "drops" +version = "0.1.0" +edition = "2021" + + +[dependencies] +entity = { workspace = true } +maps = { workspace = true } +stats = { workspace = true } + +rand = { workspace = true } +rand_chacha = { workspace = true } +serde = { workspace = true } +enum-utils = { workspace = true } +toml = { workspace = true } +chrono = { workspace = true } \ No newline at end of file diff --git a/src/ship/drops/box_drop_table.rs b/drops/src/box_drop_table.rs similarity index 95% rename from src/ship/drops/box_drop_table.rs rename to drops/src/box_drop_table.rs index e5e6f8d..01f41eb 100644 --- a/src/ship/drops/box_drop_table.rs +++ b/drops/src/box_drop_table.rs @@ -5,14 +5,14 @@ use serde::{Serialize, Deserialize}; use entity::character::SectionID; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; -use crate::ship::drops::{ItemDropType, load_data_file}; +use crate::{ItemDropType, load_data_file}; use maps::object::{MapObject, MapObjectType, FixedBoxDropType}; -use crate::ship::drops::rare_drop_table::{RareDropTable, RareDropItem}; -use crate::ship::drops::generic_weapon::GenericWeaponTable; -use crate::ship::drops::generic_armor::GenericArmorTable; -use crate::ship::drops::generic_shield::GenericShieldTable; -use crate::ship::drops::generic_unit::GenericUnitTable; -use crate::ship::drops::tool_table::ToolTable; +use crate::rare_drop_table::{RareDropTable, RareDropItem}; +use crate::generic_weapon::GenericWeaponTable; +use crate::generic_armor::GenericArmorTable; +use crate::generic_shield::GenericShieldTable; +use crate::generic_unit::GenericUnitTable; +use crate::tool_table::ToolTable; #[derive(Debug, Serialize, Deserialize)] struct BoxDropRate { diff --git a/src/ship/drops/generic_armor.rs b/drops/src/generic_armor.rs similarity index 98% rename from src/ship/drops/generic_armor.rs rename to drops/src/generic_armor.rs index 4fa2667..82e9a58 100644 --- a/src/ship/drops/generic_armor.rs +++ b/drops/src/generic_armor.rs @@ -7,7 +7,7 @@ use entity::character::SectionID; use entity::item::armor::{ArmorType, Armor}; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; -use crate::ship::drops::{ItemDropType, load_data_file}; +use crate::{ItemDropType, load_data_file}; use stats::items::{armor_stats, ArmorStats}; diff --git a/src/ship/drops/generic_shield.rs b/drops/src/generic_shield.rs similarity index 98% rename from src/ship/drops/generic_shield.rs rename to drops/src/generic_shield.rs index bed92a6..c7bbf1f 100644 --- a/src/ship/drops/generic_shield.rs +++ b/drops/src/generic_shield.rs @@ -7,7 +7,7 @@ use entity::item::shield::{ShieldType, Shield}; use entity::character::SectionID; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; -use crate::ship::drops::{ItemDropType, load_data_file}; +use crate::{ItemDropType, load_data_file}; use stats::items::{shield_stats, ShieldStats}; diff --git a/src/ship/drops/generic_unit.rs b/drops/src/generic_unit.rs similarity index 98% rename from src/ship/drops/generic_unit.rs rename to drops/src/generic_unit.rs index a5e1da5..cc1caa0 100644 --- a/src/ship/drops/generic_unit.rs +++ b/drops/src/generic_unit.rs @@ -7,7 +7,7 @@ use entity::character::SectionID; use entity::item::unit::{UnitType, Unit, UnitModifier}; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; -use crate::ship::drops::{ItemDropType, load_data_file}; +use crate::{ItemDropType, load_data_file}; use stats::items::{unit_stats, UnitStats}; diff --git a/src/ship/drops/generic_weapon.rs b/drops/src/generic_weapon.rs similarity index 99% rename from src/ship/drops/generic_weapon.rs rename to drops/src/generic_weapon.rs index 0872c8e..557130c 100644 --- a/src/ship/drops/generic_weapon.rs +++ b/drops/src/generic_weapon.rs @@ -8,7 +8,7 @@ use entity::character::SectionID; use entity::item::weapon::{Weapon, WeaponType, Attribute, WeaponAttribute, WeaponSpecial}; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; -use crate::ship::drops::{ItemDropType, load_data_file}; +use crate::{ItemDropType, load_data_file}; diff --git a/src/ship/drops/mod.rs b/drops/src/lib.rs similarity index 96% rename from src/ship/drops/mod.rs rename to drops/src/lib.rs index 5c228e0..bccffd4 100644 --- a/src/ship/drops/mod.rs +++ b/drops/src/lib.rs @@ -5,7 +5,6 @@ // to their drops -mod drop_table; pub mod rare_drop_table; mod generic_weapon; mod generic_armor; @@ -26,13 +25,13 @@ use maps::monster::MonsterType; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; use entity::character::SectionID; -use crate::ship::drops::generic_weapon::GenericWeaponTable; -use crate::ship::drops::generic_armor::GenericArmorTable; -use crate::ship::drops::generic_shield::GenericShieldTable; -use crate::ship::drops::generic_unit::GenericUnitTable; -use crate::ship::drops::tool_table::ToolTable; -use crate::ship::drops::rare_drop_table::RareDropTable; -use crate::ship::drops::box_drop_table::BoxDropTable; +use crate::generic_weapon::GenericWeaponTable; +use crate::generic_armor::GenericArmorTable; +use crate::generic_shield::GenericShieldTable; +use crate::generic_unit::GenericUnitTable; +use crate::tool_table::ToolTable; +use crate::rare_drop_table::RareDropTable; +use crate::box_drop_table::BoxDropTable; use maps::object::MapObject; use entity::item::{ItemType, weapon, armor, shield, unit, mag, tool, tech, esweapon}; diff --git a/src/ship/drops/rare_drop_table.rs b/drops/src/rare_drop_table.rs similarity index 96% rename from src/ship/drops/rare_drop_table.rs rename to drops/src/rare_drop_table.rs index 0eb6cc8..b9ab745 100644 --- a/src/ship/drops/rare_drop_table.rs +++ b/drops/src/rare_drop_table.rs @@ -11,10 +11,10 @@ use entity::character::SectionID; use maps::monster::MonsterType; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; -use crate::ship::drops::{ItemDropType, load_data_file}; -use crate::ship::drops::generic_weapon::AttributeTable; -use crate::ship::drops::generic_armor::GenericArmorTable; -use crate::ship::drops::generic_shield::GenericShieldTable; +use crate::{ItemDropType, load_data_file}; +use crate::generic_weapon::AttributeTable; +use crate::generic_armor::GenericArmorTable; +use crate::generic_shield::GenericShieldTable; type ItemParseFn = Box Option>; diff --git a/src/ship/drops/tech_table.rs b/drops/src/tech_table.rs similarity index 98% rename from src/ship/drops/tech_table.rs rename to drops/src/tech_table.rs index 79bf095..9b1101b 100644 --- a/src/ship/drops/tech_table.rs +++ b/drops/src/tech_table.rs @@ -7,7 +7,7 @@ use entity::item::tech::{Technique, TechniqueDisk}; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; use entity::character::SectionID; -use crate::ship::drops::{ItemDropType, load_data_file}; +use crate::{ItemDropType, load_data_file}; diff --git a/src/ship/drops/tool_table.rs b/drops/src/tool_table.rs similarity index 98% rename from src/ship/drops/tool_table.rs rename to drops/src/tool_table.rs index 0ce9e6d..9645c34 100644 --- a/src/ship/drops/tool_table.rs +++ b/drops/src/tool_table.rs @@ -7,8 +7,8 @@ use entity::item::tool::{Tool, ToolType}; use maps::room::{Difficulty, Episode}; use maps::area::MapArea; use entity::character::SectionID; -use crate::ship::drops::{ItemDropType, load_data_file}; -use crate::ship::drops::tech_table::TechniqueTable; +use crate::{ItemDropType, load_data_file}; +use crate::tech_table::TechniqueTable; #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, enum_utils::FromStr)] diff --git a/items/Cargo.toml b/items/Cargo.toml new file mode 100644 index 0000000..84ce90c --- /dev/null +++ b/items/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "items" +version = "0.1.0" +edition = "2021" + +[dependencies] +entity = { workspace = true } +maps = { workspace = true } +shops = { workspace = true } +location = { workspace = true } +drops = { workspace = true } + +libpso = { workspace = true } + +enum-utils = { workspace = true } +derive_more = { workspace = true } +serde = { workspace = true } +rand = { workspace = true } +rand_chacha = { workspace = true } +async-recursion = { workspace = true } +async-std = { workspace = true } +async-trait = { workspace = true } +futures = { workspace = true } +anyhow = { workspace = true } +thiserror = { workspace = true } \ No newline at end of file diff --git a/src/ship/items/actions.rs b/items/src/actions.rs similarity index 97% rename from src/ship/items/actions.rs rename to items/src/actions.rs index f5f93f0..873e735 100644 --- a/src/ship/items/actions.rs +++ b/items/src/actions.rs @@ -1,5 +1,5 @@ // TODO: replace various u32s and usizes denoting item amounts for ItemAmount(u32) for consistency -use crate::ship::items::ClientItemId; +use crate::ClientItemId; use entity::item::{Meseta, ItemNote}; use async_std::sync::Arc; use std::future::Future; @@ -15,16 +15,15 @@ use entity::item::{ItemDetail, NewItemEntity, TradeId, ItemModifier}; use entity::item::tool::Tool; use entity::room::RoomEntityId; use maps::area::MapArea; -use crate::ship::ship::SendShipPacket; -use crate::ship::items::state::{ItemStateProxy, ItemStateError, AddItemResult, StackedItemDetail, IndividualItemDetail}; -use crate::ship::items::bank::{BankItem, BankItemDetail}; -use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail}; -use crate::ship::items::floor::{FloorItem, FloorItemDetail}; -use crate::ship::items::apply_item::{apply_item, ApplyItemAction}; +use crate::state::{ItemStateProxy, ItemStateError, AddItemResult, StackedItemDetail, IndividualItemDetail}; +use crate::bank::{BankItem, BankItemDetail}; +use crate::inventory::{InventoryItem, InventoryItemDetail}; +use crate::floor::{FloorItem, FloorItemDetail}; +use crate::apply_item::{apply_item, ApplyItemAction}; use shops::ShopItem; -use crate::ship::drops::{ItemDrop, ItemDropType}; -use crate::ship::packet::builder; -use crate::ship::location::AreaClient; +use drops::{ItemDrop, ItemDropType}; +//use crate::ship::packet::builder; +use location::AreaClient; use maps::monster::MonsterType; pub enum TriggerCreateItem { @@ -32,6 +31,12 @@ pub enum TriggerCreateItem { No } +#[derive(Clone)] +pub enum CreateItem { + Individual(AreaClient, ClientItemId, IndividualItemDetail), + Stacked(AreaClient, ClientItemId, Tool, usize), +} + pub(super) fn take_item_from_floor<'a, EG, TR>( character_id: CharacterEntityId, item_id: ClientItemId @@ -1144,7 +1149,7 @@ pub(super) fn apply_item_action_packets<'a, EG, TR>( character_id: CharacterEntityId, area_client: AreaClient, ) -> impl Fn((ItemStateProxy, TR), ApplyItemAction) - -> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec), anyhow::Error>> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec), anyhow::Error>> where EG: EntityGateway, TR: EntityGatewayTransaction + 'a, @@ -1161,7 +1166,8 @@ where let (inventory_item_detail, create_item) = if item_detail.is_stackable() { let tool = item_detail.as_tool().ok_or_else(|| ItemStateError::NotATool(ClientItemId(0xFFFFFFFF)))?; - let create_item = builder::message::create_stacked_item(area_client, item_id, &tool, 1).map_err(|_err| ItemStateError::Dummy)?; + //let create_item = builder::message::create_stacked_item(area_client, item_id, &tool, 1).map_err(|_err| ItemStateError::Dummy)?; + let create_item = CreateItem::Stacked(area_client, item_id, tool.clone(), 1); let item_detail = StackedItemDetail { entity_ids: vec![new_item.id], tool @@ -1173,7 +1179,8 @@ where entity_id: new_item.id, item: item_detail, }; - let create_item = builder::message::create_individual_item(area_client, item_id, &item_detail).map_err(|_err| ItemStateError::Dummy)?; + //let create_item = builder::message::create_individual_item(area_client, item_id, &item_detail).map_err(|_err| ItemStateError::Dummy)?; + let create_item = CreateItem::Individual(area_client, item_id, item_detail.clone()); (InventoryItemDetail::Individual(item_detail), create_item) }; @@ -1187,7 +1194,8 @@ where transaction.gateway().set_character_inventory(&character_id, &inventory.as_inventory_entity(&character_id)).await?; item_state.set_inventory(inventory).await; - vec![SendShipPacket::Message(Message::new(GameMessage::CreateItem(create_item)))] + //vec![SendShipPacket::Message(Message::new(GameMessage::CreateItem(create_item)))] + vec![create_item] } else { Vec::new() diff --git a/src/ship/items/apply_item.rs b/items/src/apply_item.rs similarity index 99% rename from src/ship/items/apply_item.rs rename to items/src/apply_item.rs index ef0e05f..0f74627 100644 --- a/src/ship/items/apply_item.rs +++ b/items/src/apply_item.rs @@ -11,8 +11,8 @@ use entity::item::tool::{Tool, ToolType}; use entity::item::tech::TechniqueDisk; use entity::item::{ItemDetail, ItemEntityId}; use entity::item::weapon::WeaponModifier; -use crate::ship::items::state::ItemStateProxy; -use crate::ship::items::inventory::InventoryItemDetail; +use crate::state::ItemStateProxy; +use crate::inventory::InventoryItemDetail; #[derive(Error, Debug)] diff --git a/src/ship/items/bank.rs b/items/src/bank.rs similarity index 97% rename from src/ship/items/bank.rs rename to items/src/bank.rs index 885aba4..e68700a 100644 --- a/src/ship/items/bank.rs +++ b/items/src/bank.rs @@ -1,15 +1,15 @@ use std::cmp::Ordering; use libpso::character::character; -use crate::ship::items::ClientItemId; +use crate::ClientItemId; use entity::item::{Meseta, ItemEntityId, ItemDetail, ItemEntity, BankEntity, BankItemEntity}; use std::future::Future; use async_std::sync::{Arc, Mutex}; use entity::character::CharacterEntityId; use entity::item::BankIdentifier; -use crate::ship::items::state::ItemStateError; -use crate::ship::items::state::{IndividualItemDetail, StackedItemDetail, AddItemResult}; -use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail}; +use crate::state::ItemStateError; +use crate::state::{IndividualItemDetail, StackedItemDetail, AddItemResult}; +use crate::inventory::{InventoryItem, InventoryItemDetail}; #[derive(thiserror::Error, Debug)] diff --git a/src/ship/items/floor.rs b/items/src/floor.rs similarity index 94% rename from src/ship/items/floor.rs rename to items/src/floor.rs index 6d03133..29b79fa 100644 --- a/src/ship/items/floor.rs +++ b/items/src/floor.rs @@ -1,4 +1,4 @@ -use crate::ship::items::ClientItemId; +use crate::ClientItemId; use entity::item::{Meseta, ItemEntityId, ItemDetail}; use std::future::Future; @@ -6,9 +6,9 @@ use maps::area::MapArea; use entity::character::CharacterEntityId; use entity::item::mag::Mag; -use crate::ship::items::state::ItemStateError; -use crate::ship::items::state::{IndividualItemDetail, StackedItemDetail}; -use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail}; +use crate::state::ItemStateError; +use crate::state::{IndividualItemDetail, StackedItemDetail}; +use crate::inventory::{InventoryItem, InventoryItemDetail}; pub enum FloorType { Local, diff --git a/src/ship/items/inventory.rs b/items/src/inventory.rs similarity index 98% rename from src/ship/items/inventory.rs rename to items/src/inventory.rs index e30eb93..d8c0da9 100644 --- a/src/ship/items/inventory.rs +++ b/items/src/inventory.rs @@ -1,6 +1,6 @@ use std::cmp::Ordering; use libpso::character::character; -use crate::ship::items::ClientItemId; +use crate::ClientItemId; use entity::item::{Meseta, ItemEntityId, ItemDetail, ItemEntity, InventoryEntity, InventoryItemEntity, EquippedEntity}; use std::future::Future; use async_std::sync::{Arc, Mutex}; @@ -10,9 +10,9 @@ use entity::item::tool::ToolType; use entity::item::mag::Mag; use entity::item::weapon::Weapon; use shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem}; -use crate::ship::items::state::ItemStateError; -use crate::ship::items::state::{IndividualItemDetail, StackedItemDetail, AddItemResult}; -use crate::ship::items::floor::{FloorItem, FloorItemDetail}; +use crate::state::ItemStateError; +use crate::state::{IndividualItemDetail, StackedItemDetail, AddItemResult}; +use crate::floor::{FloorItem, FloorItemDetail}; #[derive(Clone, Debug)] pub enum InventoryItemDetail { diff --git a/src/ship/items/itemstateaction.rs b/items/src/itemstateaction.rs similarity index 100% rename from src/ship/items/itemstateaction.rs rename to items/src/itemstateaction.rs diff --git a/src/ship/items/mod.rs b/items/src/lib.rs similarity index 87% rename from src/ship/items/mod.rs rename to items/src/lib.rs index 549ee51..7f4251f 100644 --- a/src/ship/items/mod.rs +++ b/items/src/lib.rs @@ -1,3 +1,5 @@ +#![feature(extract_if)] + pub mod state; pub mod actions; pub mod apply_item; @@ -6,6 +8,7 @@ pub mod inventory; pub mod floor; pub mod bank; pub mod tasks; +pub mod trade; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize, derive_more::Display)] pub struct ClientItemId(pub u32); diff --git a/src/ship/items/manager.rs b/items/src/manager.rs similarity index 99% rename from src/ship/items/manager.rs rename to items/src/manager.rs index e9251c4..d368ec6 100644 --- a/src/ship/items/manager.rs +++ b/items/src/manager.rs @@ -1,4 +1,4 @@ -use crate::ship::items::ClientItemId; +use crate::ClientItemId; use std::collections::HashMap; use std::cmp::Ordering; use std::cell::RefCell; @@ -9,18 +9,18 @@ use crate::entity::item::{ItemDetail, ItemNote, BankName}; use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, InventoryItemEntity, BankItemEntity}; use crate::entity::item::tool::{Tool, ToolType}; use crate::entity::item::weapon; -use crate::ship::map::MapArea; +use maps::area::MapArea; use crate::ship::ship::ItemDropLocation; use crate::ship::trade::TradeItem; -use crate::ship::drops::{ItemDrop, ItemDropType}; -use crate::ship::location::{AreaClient, RoomId}; -use crate::ship::shops::ShopItem; +use drops::{ItemDrop, ItemDropType}; +use location::{AreaClient, RoomId}; +use shops::ShopItem; use crate::ship::packet::handler::trade::{TradeError, OTHER_MESETA_ITEM_ID}; -use crate::ship::items::bank::*; -use crate::ship::items::floor::*; -use crate::ship::items::inventory::*; -use crate::ship::items::transaction::{ItemTransaction, ItemAction, TransactionError, TransactionCommitError}; +use crate::bank::*; +use crate::floor::*; +use crate::inventory::*; +use crate::transaction::{ItemTransaction, ItemAction, TransactionError, TransactionCommitError}; #[derive(PartialEq, Eq)] pub enum FloorType { diff --git a/src/ship/items/state.rs b/items/src/state.rs similarity index 97% rename from src/ship/items/state.rs rename to items/src/state.rs index 9058c05..aa27143 100644 --- a/src/ship/items/state.rs +++ b/items/src/state.rs @@ -10,12 +10,12 @@ use entity::item::{ItemEntityId, ItemDetail, ItemEntity, InventoryItemEntity, Ba use entity::item::tool::Tool; use entity::item::weapon::Weapon; use entity::item::mag::Mag; -use crate::ship::drops::ItemDrop; -use crate::ship::items::ClientItemId; -use crate::ship::items::inventory::{Inventory, InventoryItem, InventoryItemDetail, InventoryError, InventoryState}; -use crate::ship::items::floor::{FloorState, FloorItem, LocalFloor, SharedFloor, FloorType}; -use crate::ship::items::bank::{Bank, BankState, BankItem, BankItemDetail, BankError}; -use crate::ship::location::{AreaClient, RoomId}; +use drops::ItemDrop; +use crate::ClientItemId; +use crate::inventory::{Inventory, InventoryItem, InventoryItemDetail, InventoryError, InventoryState}; +use crate::floor::{FloorState, FloorItem, LocalFloor, SharedFloor, FloorType}; +use crate::bank::{Bank, BankState, BankItem, BankItemDetail, BankError}; +use location::{AreaClient, RoomId}; #[derive(thiserror::Error, Debug)] pub enum ItemStateError { @@ -50,7 +50,7 @@ pub enum ItemStateError { #[error("stacked item")] StackedItemError(Vec), #[error("apply item {0}")] - ApplyItemError(#[from] crate::ship::items::apply_item::ApplyItemError), + ApplyItemError(#[from] crate::apply_item::ApplyItemError), #[error("item is not a mag {0}")] NotAMag(ClientItemId), #[error("item is not mag food {0}")] diff --git a/src/ship/items/tasks.rs b/items/src/tasks.rs similarity index 97% rename from src/ship/items/tasks.rs rename to items/src/tasks.rs index d4910a1..8a7a307 100644 --- a/src/ship/items/tasks.rs +++ b/items/src/tasks.rs @@ -1,24 +1,23 @@ use futures::future::BoxFuture; -use crate::ship::items::ClientItemId; +use crate::ClientItemId; use entity::item::Meseta; -use crate::ship::ship::SendShipPacket; use maps::area::MapArea; use entity::character::{CharacterEntity, CharacterEntityId}; use entity::gateway::{EntityGateway, EntityGatewayTransaction}; use entity::item::ItemModifier; use entity::room::RoomEntityId; -use crate::ship::items::state::{ItemState, ItemStateProxy, IndividualItemDetail}; -use crate::ship::items::itemstateaction::{ItemStateAction, ItemAction}; -use crate::ship::items::inventory::InventoryItem; -use crate::ship::items::floor::FloorItem; +use crate::state::{ItemState, ItemStateProxy, IndividualItemDetail}; +use crate::itemstateaction::{ItemStateAction, ItemAction}; +use crate::inventory::InventoryItem; +use crate::floor::FloorItem; use shops::ShopItem; -use crate::ship::trade::TradeItem; -use crate::ship::location::AreaClient; -use crate::ship::drops::ItemDrop; +use crate::trade::TradeItem; +use location::AreaClient; +use drops::ItemDrop; use maps::monster::MonsterType; -use crate::ship::items::actions; +use crate::actions; pub fn pick_up_item<'a, EG>( item_state: &'a mut ItemState, @@ -278,7 +277,7 @@ pub fn use_item<'a, EG> ( area_client: AreaClient, item_id: &'a ClientItemId, amount: u32, -) -> BoxFuture<'a, Result, anyhow::Error>> +) -> BoxFuture<'a, Result, anyhow::Error>> where EG: EntityGateway + 'static, { diff --git a/items/src/trade.rs b/items/src/trade.rs new file mode 100644 index 0000000..19e49bc --- /dev/null +++ b/items/src/trade.rs @@ -0,0 +1,38 @@ +use crate::ClientItemId; + +#[derive(Debug, Clone)] +pub enum TradeItem { + Individual(ClientItemId), + Stacked(ClientItemId, usize), +} + +impl TradeItem { + pub fn stacked(&self) -> Option<(ClientItemId, usize)> { + match self { + TradeItem::Stacked(item_id, amount) => Some((*item_id, *amount)), + _ => None + } + } + + pub fn stacked_mut(&mut self) -> Option<(ClientItemId, &mut usize)> { + match self { + TradeItem::Stacked(item_id, ref mut amount) => Some((*item_id, amount)), + _ => None + } + } + + pub fn item_id(&self) -> ClientItemId { + match self { + TradeItem::Individual(item_id) => *item_id, + TradeItem::Stacked(item_id, _) => *item_id, + } + } + + pub fn amount(&self) -> usize { + match self { + TradeItem::Individual(_) => 1, + TradeItem::Stacked(_, amount) => *amount, + } + } +} + diff --git a/location/Cargo.toml b/location/Cargo.toml new file mode 100644 index 0000000..f6768c0 --- /dev/null +++ b/location/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "location" +version = "0.1.0" +edition = "2021" + +[dependencies] +networking = { workspace = true } + +async-std = { workspace = true } +derive_more = { workspace = true } +futures= { workspace = true } +thiserror = { workspace = true } \ No newline at end of file diff --git a/location/src/lib.rs b/location/src/lib.rs new file mode 100644 index 0000000..dd9bd1e --- /dev/null +++ b/location/src/lib.rs @@ -0,0 +1,3 @@ +pub mod location; + +pub use location::*; diff --git a/src/ship/location.rs b/location/src/location.rs similarity index 99% rename from src/ship/location.rs rename to location/src/location.rs index 5dc805e..3dd0b2b 100644 --- a/src/ship/location.rs +++ b/location/src/location.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::time::SystemTime; use thiserror::Error; -use crate::common::serverstate::ClientId; +use networking::serverstate::ClientId; use async_std::sync::{Arc, RwLock}; use futures::{stream, StreamExt}; diff --git a/maps/src/enemy.rs b/maps/src/enemy.rs index 033b05d..54ac36d 100644 --- a/maps/src/enemy.rs +++ b/maps/src/enemy.rs @@ -9,17 +9,11 @@ use thiserror::Error; use rand::{Rng, SeedableRng}; use serde::{Serialize, Deserialize}; +use crate::Holiday; use crate::area::{MapArea, MapAreaError}; use crate::room::Episode; use crate::monster::MonsterType; -#[derive(Clone, Copy)] -pub enum RareEnemyEvent { - Easter, - Halloween, - Christmas, -} - #[derive(Debug, Copy, Clone)] pub struct RawMapEnemy { id: u32, @@ -120,7 +114,7 @@ impl RareMonsterAppearTable { rand_chacha::ChaChaRng::from_entropy().gen::() < *self.appear_rate.get(monster).unwrap_or(&0.0f32) } - pub fn apply(&self, enemy: MapEnemy, event: Option) -> MapEnemy { + pub fn apply(&self, enemy: MapEnemy, event: Holiday) -> MapEnemy { if enemy.can_be_rare() && self.roll_is_rare(&enemy.monster) { enemy.into_rare(event) } @@ -362,12 +356,12 @@ impl MapEnemy { guaranteed rare monsters don't count towards the limit */ #[must_use] - pub fn into_rare(self, event: Option) -> MapEnemy { + pub fn into_rare(self, event: Holiday) -> MapEnemy { match (self.monster, self.map_area.to_episode(), event) { (MonsterType::RagRappy, Episode::One, _) => {MapEnemy {monster: MonsterType::AlRappy, shiny:true, ..self}}, - (MonsterType::RagRappy, Episode::Two, Some(RareEnemyEvent::Easter)) => {MapEnemy {monster: MonsterType::EasterRappy, shiny:true, ..self}}, - (MonsterType::RagRappy, Episode::Two, Some(RareEnemyEvent::Halloween)) => {MapEnemy {monster: MonsterType::HalloRappy, shiny:true, ..self}}, - (MonsterType::RagRappy, Episode::Two, Some(RareEnemyEvent::Christmas)) => {MapEnemy {monster: MonsterType::StRappy, shiny:true, ..self}}, + (MonsterType::RagRappy, Episode::Two, Holiday::Easter) => {MapEnemy {monster: MonsterType::EasterRappy, shiny:true, ..self}}, + (MonsterType::RagRappy, Episode::Two, Holiday::Halloween) => {MapEnemy {monster: MonsterType::HalloRappy, shiny:true, ..self}}, + (MonsterType::RagRappy, Episode::Two, Holiday::Christmas) => {MapEnemy {monster: MonsterType::StRappy, shiny:true, ..self}}, (MonsterType::RagRappy, Episode::Two, _) => {MapEnemy {monster: MonsterType::LoveRappy, shiny:true, ..self}}, (MonsterType::Hildebear, _, _) => {MapEnemy {monster: MonsterType::Hildeblue, shiny:true, ..self}}, (MonsterType::PoisonLily, _, _) => {MapEnemy {monster: MonsterType::NarLily, shiny:true, ..self}}, diff --git a/maps/src/lib.rs b/maps/src/lib.rs index fa2b60e..2da528c 100644 --- a/maps/src/lib.rs +++ b/maps/src/lib.rs @@ -5,3 +5,55 @@ pub mod variant; pub mod maps; pub mod monster; pub mod room; + +#[derive(Clone, Copy)] +pub enum Holiday { + None, + Christmas, + Valentines, + Easter, + Halloween, + Sonic, + NewYear, + Summer, + White, + Wedding, + Fall, + Spring, + Summer2, + Spring2, +} + + +impl From for u32 { + fn from(other: Holiday) -> u32 { + u16::from(other) as u32 + } +} + +impl From for u16 { + fn from(other: Holiday) -> u16 { + u8::from(other) as u16 + } +} + +impl From for u8 { + fn from(other: Holiday) -> u8 { + match other { + Holiday::None => 0, + Holiday::Christmas => 1, + Holiday::Valentines => 3, + Holiday::Easter => 4, + Holiday::Halloween => 5, + Holiday::Sonic => 6, + Holiday::NewYear => 7, + Holiday::Summer => 8, + Holiday::White => 9, + Holiday::Wedding => 10, + Holiday::Fall => 11, + Holiday::Spring => 12, + Holiday::Summer2 => 13, + Holiday::Spring2 => 14, + } + } +} diff --git a/maps/src/maps.rs b/maps/src/maps.rs index 6684d52..4ca76d9 100644 --- a/maps/src/maps.rs +++ b/maps/src/maps.rs @@ -9,7 +9,8 @@ use thiserror::Error; //use crate::ship::ship::ShipEvent; use crate::area::MapArea; -use crate::enemy::{MapEnemy, RawMapEnemy, RareEnemyEvent, RareMonsterAppearTable}; +use crate::Holiday; +use crate::enemy::{MapEnemy, RawMapEnemy, RareMonsterAppearTable}; use crate::monster::MonsterType; use crate::variant::{MapVariant, MapVariantMode}; use crate::object::{MapObject, RawMapObject}; @@ -325,7 +326,7 @@ impl Maps { enemies: Vec>, objects: Vec>, rare_monster_table: &RareMonsterAppearTable, - event: Option) + event: Holiday) { self.enemy_data = enemies .into_iter() @@ -358,7 +359,7 @@ impl Maps { } } -pub fn generate_free_roam_maps(room_mode: RoomMode, event: Option) -> Maps { +pub fn generate_free_roam_maps(room_mode: RoomMode, event: Holiday) -> Maps { let rare_monster_table = RareMonsterAppearTable::new(room_mode.episode()); let map_variants = default_map_variants(room_mode.episode(), room_mode.player_mode()); Maps { diff --git a/networking/Cargo.toml b/networking/Cargo.toml index b0ee8a2..1ecadc9 100644 --- a/networking/Cargo.toml +++ b/networking/Cargo.toml @@ -2,3 +2,17 @@ name = "networking" version = "0.1.0" edition = "2021" + + +[dependencies] +entity = { workspace = true } + +libpso = { workspace = true } + +async-std = { workspace = true } +async-trait = { workspace = true } +futures = { workspace = true } +log = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +derive_more = { workspace = true } \ No newline at end of file diff --git a/src/common/cipherkeys.rs b/networking/src/cipherkeys.rs similarity index 100% rename from src/common/cipherkeys.rs rename to networking/src/cipherkeys.rs diff --git a/src/common/interserver.rs b/networking/src/interserver.rs similarity index 100% rename from src/common/interserver.rs rename to networking/src/interserver.rs diff --git a/networking/src/lib.rs b/networking/src/lib.rs index e69de29..c8adde9 100644 --- a/networking/src/lib.rs +++ b/networking/src/lib.rs @@ -0,0 +1,18 @@ +pub mod cipherkeys; +pub mod serverstate; +pub mod mainloop; +pub mod interserver; + +// https://www.reddit.com/r/rust/comments/33xhhu/how_to_create_an_array_of_structs_that_havent/ +#[macro_export] +macro_rules! init_array( + ($ty:ty, $len:expr, $val:expr) => ( + { + let mut array: [$ty; $len] = unsafe { std::mem::uninitialized() }; + for i in array.iter_mut() { + unsafe { ::std::ptr::write(i, $val); } + } + array + } + ) +); diff --git a/src/common/mainloop/client.rs b/networking/src/mainloop/client.rs similarity index 97% rename from src/common/mainloop/client.rs rename to networking/src/mainloop/client.rs index d7af211..3bcb971 100644 --- a/src/common/mainloop/client.rs +++ b/networking/src/mainloop/client.rs @@ -9,8 +9,8 @@ use log::{trace, info, warn, error}; use libpso::crypto::{PSOCipher, NullCipher, CipherError}; use libpso::PacketParseError; -use crate::common::serverstate::ClientId; -use crate::common::serverstate::{RecvServerPacket, SendServerPacket, ServerState, OnConnect}; +use crate::serverstate::ClientId; +use crate::serverstate::{RecvServerPacket, SendServerPacket, ServerState, OnConnect}; #[derive(Debug)] @@ -255,7 +255,7 @@ where let (mut socket, addr) = listener.accept().await.unwrap(); id += 1; - let client_id = crate::common::serverstate::ClientId(id); + let client_id = crate::serverstate::ClientId(id); info!("new client {:?} {:?} {:?}", client_id, socket, addr); let (client_tx, client_rx) = async_std::channel::unbounded(); diff --git a/src/common/mainloop/interserver.rs b/networking/src/mainloop/interserver.rs similarity index 95% rename from src/common/mainloop/interserver.rs rename to networking/src/mainloop/interserver.rs index 0465f43..5e5194b 100644 --- a/src/common/mainloop/interserver.rs +++ b/networking/src/mainloop/interserver.rs @@ -8,11 +8,10 @@ use std::collections::HashMap; use serde::Serialize; use serde::de::DeserializeOwned; -use crate::common::interserver::{ServerId, InterserverActor}; +use crate::interserver::{ServerId, InterserverActor}; use libpso::crypto::{PSOCipher, NullCipher, CipherError}; -use crate::common::serverstate::{ServerState, SendServerPacket, RecvServerPacket}; -use crate::login::character::CharacterServerState; +use crate::serverstate::{ServerState, SendServerPacket, RecvServerPacket}; use entity::gateway::entitygateway::EntityGateway; use async_std::channel; @@ -148,7 +147,7 @@ where info!("[interserver listen] new server: {:?} {:?}", socket, addr); id += 1; - let server_id = crate::common::interserver::ServerId(id); + let server_id = crate::interserver::ServerId(id); let (client_tx, client_rx) = async_std::channel::unbounded(); state.set_sender(server_id, client_tx.clone()).await; @@ -195,7 +194,7 @@ where } }; id += 1; - let server_id = crate::common::interserver::ServerId(id); + let server_id = crate::interserver::ServerId(id); info!("[interserver connect] found loginserv: {:?} {:?}", server_id, socket); let (client_tx, client_rx) = async_std::channel::unbounded(); diff --git a/src/common/mainloop/mod.rs b/networking/src/mainloop/mod.rs similarity index 100% rename from src/common/mainloop/mod.rs rename to networking/src/mainloop/mod.rs diff --git a/src/common/serverstate.rs b/networking/src/serverstate.rs similarity index 100% rename from src/common/serverstate.rs rename to networking/src/serverstate.rs diff --git a/pktbuilder/Cargo.toml b/pktbuilder/Cargo.toml new file mode 100644 index 0000000..9c070f9 --- /dev/null +++ b/pktbuilder/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "pktbuilder" +version = "0.1.0" +edition = "2021" + +[dependencies] +quests = { workspace = true } +stats = { workspace = true } +location = { workspace = true } +client = { workspace = true } +items = { workspace = true } +networking = { workspace = true } +maps = { workspace = true } +room = { workspace = true } +shops = { workspace = true } +entity = { workspace = true } + +libpso = { workspace = true } + +anyhow = { workspace = true } +futures = { workspace = true } +thiserror = { workspace = true } \ No newline at end of file diff --git a/src/ship/character.rs b/pktbuilder/src/character.rs similarity index 98% rename from src/ship/character.rs rename to pktbuilder/src/character.rs index 90ba63b..5d57896 100644 --- a/src/ship/character.rs +++ b/pktbuilder/src/character.rs @@ -1,9 +1,8 @@ use libpso::character::character; use stats::leveltable::CharacterStats; use entity::character::CharacterEntity; -//use crate::ship::items::{CharacterInventory, CharacterBank}; -use crate::ship::items::bank::BankState; -use crate::ship::items::inventory::InventoryState; +use items::bank::BankState; +use items::inventory::InventoryState; use entity::item::Meseta; diff --git a/src/ship/packet/builder/mod.rs b/pktbuilder/src/lib.rs similarity index 88% rename from src/ship/packet/builder/mod.rs rename to pktbuilder/src/lib.rs index 4872aaa..bdcd755 100644 --- a/src/ship/packet/builder/mod.rs +++ b/pktbuilder/src/lib.rs @@ -3,14 +3,15 @@ pub mod message; pub mod room; pub mod quest; pub mod ship; +pub mod character; use libpso::character::character::Inventory; use libpso::packet::ship::{PlayerHeader, PlayerInfo}; use stats::leveltable::LEVEL_TABLE; -use crate::ship::character::CharacterBytesBuilder; -use crate::ship::ship::ClientState; -use crate::ship::location::AreaClient; -use crate::ship::items::inventory::InventoryState; +use crate::character::CharacterBytesBuilder; +use client::ClientState; +use location::AreaClient; +use items::inventory::InventoryState; pub fn player_header(tag: u32, client: &ClientState, area_client: &AreaClient) -> PlayerHeader { PlayerHeader { diff --git a/src/ship/packet/builder/lobby.rs b/pktbuilder/src/lobby.rs similarity index 91% rename from src/ship/packet/builder/lobby.rs rename to pktbuilder/src/lobby.rs index af033ca..34587c5 100644 --- a/src/ship/packet/builder/lobby.rs +++ b/pktbuilder/src/lobby.rs @@ -1,9 +1,10 @@ use libpso::packet::ship::*; -use crate::common::serverstate::ClientId; -use crate::ship::ship::{Clients, ShipEvent}; -use crate::ship::location::{ClientLocation, LobbyId, ClientLocationError}; -use crate::ship::packet::builder::{player_info}; -use crate::ship::items::state::ItemState; +use networking::serverstate::ClientId; +use maps::Holiday; +use client::Clients; +use location::{ClientLocation, LobbyId, ClientLocationError}; +use crate::player_info; +use items::state::ItemState; use futures::future::join_all; @@ -12,7 +13,7 @@ pub async fn join_lobby(id: ClientId, client_location: &ClientLocation, clients: &Clients, item_state: &ItemState, - event: ShipEvent) + event: Holiday) -> Result { let lobby_clients = client_location.get_clients_in_lobby(lobby).await.map_err(|err| -> ClientLocationError { err.into() })?; @@ -52,7 +53,7 @@ pub async fn add_to_lobby(id: ClientId, client_location: &ClientLocation, clients: &Clients, item_state: &ItemState, - event: ShipEvent) + event: Holiday) -> Result { let area_client = client_location.get_local_client(id).await.map_err(|err| -> ClientLocationError { err.into() })?; let leader = client_location.get_lobby_leader(lobby).await.map_err(|err| -> ClientLocationError { err.into() })?; diff --git a/src/ship/packet/builder/message.rs b/pktbuilder/src/message.rs similarity index 74% rename from src/ship/packet/builder/message.rs rename to pktbuilder/src/message.rs index d420187..cf843df 100644 --- a/src/ship/packet/builder/message.rs +++ b/pktbuilder/src/message.rs @@ -2,20 +2,20 @@ use libpso::packet::messages::*; use libpso::packet::ship::*; use entity::item; use stats::leveltable::CharacterStats; -use crate::ship::ship::{ShipError}; -use crate::ship::items::ClientItemId; -use crate::ship::items::inventory::InventoryItem; -use crate::ship::items::state::IndividualItemDetail; -use crate::ship::items::bank::BankState; -use crate::ship::items::floor::FloorItem; -use crate::ship::location::AreaClient; +//use crate::ship::ship::{ShipError}; +use items::ClientItemId; +use items::inventory::InventoryItem; +use items::state::IndividualItemDetail; +use items::bank::BankState; +use items::floor::FloorItem; +use location::AreaClient; use std::convert::TryInto; use shops::ShopItem; -pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem) -> Result { +pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem) -> ItemDrop { let item_bytes = item_drop.as_client_bytes(); - Ok(ItemDrop { + ItemDrop { client, target, map_area: item_drop.map_area.area_value(), @@ -24,37 +24,37 @@ pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem) -> Result Result { +pub fn create_individual_item(area_client: AreaClient, item_id: ClientItemId, item: &IndividualItemDetail) -> CreateItem { let bytes = item.as_client_bytes(); - Ok(CreateItem { + CreateItem { client: area_client.local_client.id(), target: 0, - item_data: bytes[0..12].try_into()?, + item_data: bytes[0..12].try_into().unwrap(), item_id: item_id.0, - item_data2: bytes[12..16].try_into()?, + item_data2: bytes[12..16].try_into().unwrap(), unknown: 0, - }) + } } // TODO: this doesn't need to be a Result, just unwrap try_intos they are guaranteed to succeed -pub fn create_stacked_item(area_client: AreaClient, item_id: ClientItemId, tool: &item::tool::Tool, amount: usize) -> Result { +pub fn create_stacked_item(area_client: AreaClient, item_id: ClientItemId, tool: &item::tool::Tool, amount: usize) -> CreateItem { let bytes = tool.as_stacked_bytes(amount); - Ok(CreateItem { + CreateItem { client: area_client.local_client.id(), target: 0, - item_data: bytes[0..12].try_into()?, + item_data: bytes[0..12].try_into().unwrap(), item_id: item_id.0, - item_data2: bytes[12..16].try_into()?, + item_data2: bytes[12..16].try_into().unwrap(), unknown: 0, - }) + } } pub fn create_meseta(area_client: AreaClient, amount: usize) -> CreateItem { @@ -69,32 +69,32 @@ pub fn create_meseta(area_client: AreaClient, amount: usize) -> CreateItem { } } -pub fn create_withdrawn_inventory_item(area_client: AreaClient, item: &InventoryItem) -> Result { +pub fn create_withdrawn_inventory_item(area_client: AreaClient, item: &InventoryItem) -> CreateItem { let bytes = item.item.as_client_bytes(); - Ok(CreateItem { + CreateItem { client: area_client.local_client.id(), target: 0, - item_data: bytes[0..12].try_into()?, + item_data: bytes[0..12].try_into().unwrap(), item_id: item.item_id.0, - item_data2: bytes[12..16].try_into()?, + item_data2: bytes[12..16].try_into().unwrap(), unknown: 0, - }) + } } -pub fn create_withdrawn_inventory_item2(area_client: AreaClient, item: &InventoryItem) -> Result { +pub fn create_withdrawn_inventory_item2(area_client: AreaClient, item: &InventoryItem) -> CreateItem { let bytes = item.item.as_client_bytes(); - Ok(CreateItem { + CreateItem { client: area_client.local_client.id(), target: 0, - item_data: bytes[0..12].try_into()?, + item_data: bytes[0..12].try_into().unwrap(), item_id: item.item_id.0, - item_data2: bytes[12..16].try_into()?, + item_data2: bytes[12..16].try_into().unwrap(), unknown: 0, - }) + } } -pub fn remove_item_from_floor(area_client: AreaClient, item: &FloorItem) -> Result { - Ok(RemoveItemFromFloor { +pub fn remove_item_from_floor(area_client: AreaClient, item: &FloorItem) -> RemoveItemFromFloor { + RemoveItemFromFloor { client: area_client.local_client.id(), target: 0, client_id: area_client.local_client.id(), @@ -102,12 +102,12 @@ pub fn remove_item_from_floor(area_client: AreaClient, item: &FloorItem) -> Resu map_area: item.map_area.area_value(), unknown2: 0, item_id: item.item_id.0, - }) + } } -pub fn drop_split_stack(area_client: AreaClient, item: &FloorItem) -> Result { +pub fn drop_split_stack(area_client: AreaClient, item: &FloorItem) -> DropSplitStack { let item_bytes = item.as_client_bytes(); - Ok(DropSplitStack { + DropSplitStack { client: area_client.local_client.id(), target: 0, variety: 0, @@ -115,16 +115,16 @@ pub fn drop_split_stack(area_client: AreaClient, item: &FloorItem) -> Result Result { +pub fn drop_split_meseta_stack(area_client: AreaClient, item: &FloorItem) -> DropSplitStack { let item_bytes = item.as_client_bytes(); - Ok(DropSplitStack { + DropSplitStack { client: area_client.local_client.id(), target: 0, variety: 0, @@ -132,11 +132,11 @@ pub fn drop_split_meseta_stack(area_client: AreaClient, item: &FloorItem) -> Res map_area: item.map_area.area_value(), x: item.x, z: item.z, - item_bytes: item_bytes[0..12].try_into()?, + item_bytes: item_bytes[0..12].try_into().unwrap(), item_id: item.item_id.0, - item_bytes2: item_bytes[12..16].try_into()?, + item_bytes2: item_bytes[12..16].try_into().unwrap(), unknown2: 0, - }) + } } pub fn character_gained_exp(area_client: AreaClient, exp: u32) -> GiveCharacterExp { @@ -215,13 +215,13 @@ pub fn shop_list(shop_type: u8, items: &[I]) -> ShopList { } } -pub fn tek_preview(id: ClientItemId, weapon: &item::weapon::Weapon) -> Result { +pub fn tek_preview(id: ClientItemId, weapon: &item::weapon::Weapon) -> TekPreview { let bytes = weapon.as_bytes(); - Ok(TekPreview { + TekPreview { client: 0x79, target: 0, - item_bytes: bytes[0..12].try_into()?, + item_bytes: bytes[0..12].try_into().unwrap(), item_id: id.0, - item_bytes2: bytes[12..16].try_into()?, - }) + item_bytes2: bytes[12..16].try_into().unwrap(), + } } diff --git a/src/ship/packet/builder/quest.rs b/pktbuilder/src/quest.rs similarity index 94% rename from src/ship/packet/builder/quest.rs rename to pktbuilder/src/quest.rs index f162269..d3f2f4f 100644 --- a/src/ship/packet/builder/quest.rs +++ b/pktbuilder/src/quest.rs @@ -1,8 +1,9 @@ -use crate::ship::quests::{Quest, QuestList}; -use crate::ship::ship::{QUEST_CATEGORY_MENU_ID, QUEST_SELECT_MENU_ID}; +use quests::{Quest, QuestList}; use libpso::packet::ship::*; use libpso::{utf8_to_array, utf8_to_utf16_array}; +pub const QUEST_CATEGORY_MENU_ID: u32 = 0xA2; +pub const QUEST_SELECT_MENU_ID: u32 = 0xA3; pub fn quest_category_list(quests: &QuestList) -> QuestCategoryList { let categories = quests.iter() diff --git a/src/ship/packet/builder/room.rs b/pktbuilder/src/room.rs similarity index 85% rename from src/ship/packet/builder/room.rs rename to pktbuilder/src/room.rs index 1f922a1..a7bbe75 100644 --- a/src/ship/packet/builder/room.rs +++ b/pktbuilder/src/room.rs @@ -1,11 +1,12 @@ -use libpso::packet::ship::*; -use crate::common::serverstate::ClientId; -use crate::ship::ship::{ShipError, ClientState, Clients, ShipEvent}; -use crate::ship::location::{ClientLocation, RoomId, AreaClient, ClientLocationError}; -use crate::ship::room::RoomState; -use crate::ship::items::state::ItemState; -use crate::ship::packet::builder::{player_header, player_info}; use std::convert::TryInto; +use libpso::packet::ship::*; +use networking::serverstate::ClientId; +use maps::Holiday; +use client::{ClientState, Clients}; +use location::{ClientLocation, RoomId, AreaClient, ClientLocationError}; +use room::RoomState; +use items::state::ItemState; +use crate::{player_header, player_info}; use futures::stream::StreamExt; @@ -14,14 +15,14 @@ pub async fn join_room(id: ClientId, client_location: &ClientLocation, room_id: RoomId, room: &RoomState, - event: ShipEvent) + event: Holiday) -> Result { let all_clients = client_location.get_clients_in_room(room_id).await.map_err(|err| -> ClientLocationError { err.into() })?; #[allow(clippy::manual_try_fold)] // I don't think its even possible to make this work here let players = futures::stream::iter(all_clients.iter()) .enumerate() .fold::, _, _>(Ok([PlayerHeader::default(); 4]), |acc, (i, c)| async move { - let header_area_client = client_location.get_local_client(id).await.map_err(|err| ShipError::ClientLocationError(err.into()))?; + let header_area_client = client_location.get_local_client(id).await.map_err(|err| -> ClientLocationError {err.into() })?; clients.with(c.client, |client| Box::pin(async move { acc.map(|mut a| { a[i] = player_header(0x10000, client, &header_area_client); @@ -58,7 +59,7 @@ pub async fn add_to_room(_id: ClientId, area_client: &AreaClient, leader: &AreaClient, item_state: &ItemState, - event: ShipEvent) + event: Holiday) -> Result { let inventory = item_state.get_character_inventory(&client.character).await?; Ok(AddToRoom { diff --git a/src/ship/packet/builder/ship.rs b/pktbuilder/src/ship.rs similarity index 85% rename from src/ship/packet/builder/ship.rs rename to pktbuilder/src/ship.rs index 1411f2a..41c6ea0 100644 --- a/src/ship/packet/builder/ship.rs +++ b/pktbuilder/src/ship.rs @@ -1,8 +1,9 @@ use libpso::packet::login::{ShipList, ShipListEntry}; use libpso::utf8_to_utf16_array; -use crate::common::interserver::Ship; -use crate::login::character::SHIP_MENU_ID; +use networking::interserver::Ship; + +pub const SHIP_MENU_ID: u32 = 1; pub fn ship_list(ships: &[Ship]) -> ShipList { let ships = ships.iter() diff --git a/pktbuilder/src/team.rs b/pktbuilder/src/team.rs new file mode 100644 index 0000000..9ebdfb9 --- /dev/null +++ b/pktbuilder/src/team.rs @@ -0,0 +1,107 @@ +use futures::stream::{FuturesOrdered, StreamExt}; +use libpso::packet::ship::*; +use crate::common::serverstate::ClientId; +use crate::entity::gateway::EntityGateway; +use crate::ship::client::{Clients, ClientState}; +use crate::ship::teams::Teams; +use crate::ship::location::ClientLocation; +use crate::ship::ship::ShipError; +use crate::entity::team::TeamEntity; + + +pub fn client_team_state_changed(client_id: ClientId, client: &ClientState, team: &TeamEntity) -> ClientTeamStateChanged { + ClientTeamStateChanged { + unknown: 0, + guildcard: client.user.guildcard(), + team_id: team.id.0, + unknown2: [0;2], + privilege: 0x40, // TODO: improve + team_name: libpso::utf8_to_utf16_array!(team.name, 14), + unknown3: 0x00986C84, // TODO: what if we omit this? + } +} + +fn player_team_info(client_id: ClientId, client: &ClientState, team: &TeamEntity) -> PlayerTeamInfo { + PlayerTeamInfo { + guildcard: client.user.guildcard(), + team_id: team.id.0, + info: 0, + info2: 0, + privilege: 0x40, // TODO: improve + team_name: libpso::utf8_to_utf16_array!(team.name, 14), + unknown: 0x00986C84, // TODO: what if we omit this? + guildcard_again: client.user.guildcard(), + client_id: client_id.0 as u32, + character_name: libpso::utf8_to_utf16_array!(client.character.name, 12), + unknown2: 0, + unknown3: 0, + team_flag: team.team_flag, + } +} + +pub fn team_info_individual(client_id: ClientId, client: &ClientState, team: &TeamEntity) -> TeamInfo { + TeamInfo { + clients: vec![player_team_info(client_id, client, team)] + } +} + + +pub async fn player_team_info_list(id: ClientId, + client_location: &ClientLocation, + clients: &Clients, + teams: &Teams, +) -> Result, ShipError> +where + EG: EntityGateway + Clone + 'static, +{ + Ok(futures::stream::iter(client_location.get_all_clients_by_client(id).await?.into_iter()) + .filter_map(|area_client| { + let clients = clients.clone(); + async move { + clients.with(area_client.client, |client| { + let mut teams = teams.clone(); + Box::pin(async move { + let team = teams.get_team(area_client.client).await.ok()??; + Some(player_team_info(area_client.client, client, &team)) + })}).await.ok()? + }}) + .collect::>() + .await) +} + +pub async fn team_info(id: ClientId, + client_location: &ClientLocation, + clients: &Clients, + teams: &Teams, +) -> Result +where + EG: EntityGateway + Clone + 'static, +{ + Ok(TeamInfo { + clients: player_team_info_list(id, client_location, clients, teams).await?, + }) +} + +pub async fn lobby_team_list(id: ClientId, + client_location: &ClientLocation, + clients: &Clients, + teams: &Teams, +) -> Result +where + EG: EntityGateway + Clone + 'static, +{ + Ok(TeamLobbyList { + clients: player_team_info_list(id, client_location, clients, teams).await?, + }) +} + +pub fn team_invitation_info(client_id: ClientId, client: &ClientState, team: &TeamEntity) -> TeamInvitationInfo { + TeamInvitationInfo { + guildcard: client.user.guildcard(), + team_id: team.id.0, + unknown: [0; 2], + team_name: libpso::utf8_to_utf16_array!(team.name, 14), + unknown2: 0x00986C84, // TODO: what if we omit this? + team_flag: team.team_flag, + } +} diff --git a/src/ship/packet/builder/trade.rs b/pktbuilder/src/trade.rs similarity index 100% rename from src/ship/packet/builder/trade.rs rename to pktbuilder/src/trade.rs diff --git a/quests/Cargo.toml b/quests/Cargo.toml new file mode 100644 index 0000000..6cab926 --- /dev/null +++ b/quests/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "quests" +version = "0.1.0" +edition = "2021" + +[dependencies] +maps = { workspace = true } + +libpso = { workspace = true } + +async-std = { workspace = true } +ages-prs = { workspace = true } +log = { workspace = true } +byteorder = { workspace = true } +thiserror = { workspace = true } +anyhow = { workspace = true } +toml = { workspace = true } +serde = { workspace = true } diff --git a/quests/src/lib.rs b/quests/src/lib.rs new file mode 100644 index 0000000..de40457 --- /dev/null +++ b/quests/src/lib.rs @@ -0,0 +1,4 @@ +pub mod quests; + + +pub use quests::*; diff --git a/src/ship/quests.rs b/quests/src/quests.rs similarity index 100% rename from src/ship/quests.rs rename to quests/src/quests.rs diff --git a/room/Cargo.toml b/room/Cargo.toml new file mode 100644 index 0000000..361b597 --- /dev/null +++ b/room/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "room" +version = "0.1.0" +edition = "2021" + +[dependencies] +maps = { workspace = true } +entity = { workspace = true } +quests = { workspace = true } +location = { workspace = true } +drops = { workspace = true } + +rand= { workspace = true } +async-std = { workspace = true } +futures = { workspace = true } +anyhow = { workspace = true } +thiserror = { workspace = true } diff --git a/room/src/lib.rs b/room/src/lib.rs new file mode 100644 index 0000000..4f8d063 --- /dev/null +++ b/room/src/lib.rs @@ -0,0 +1,3 @@ +pub mod room; + +pub use room::*; diff --git a/src/ship/room.rs b/room/src/room.rs similarity index 90% rename from src/ship/room.rs rename to room/src/room.rs index 441feb5..a065d55 100644 --- a/src/ship/room.rs +++ b/room/src/room.rs @@ -8,21 +8,28 @@ use thiserror::Error; use rand::Rng; use maps::maps::Maps; -use crate::ship::drops::DropTable; +use drops::DropTable; use entity::character::SectionID; use entity::room::{RoomEntityId, RoomEntityMode}; use maps::monster::{load_monster_stats_table, MonsterType, MonsterStats}; use maps::area::MapAreaLookup; -use maps::enemy::RareEnemyEvent; -use crate::ship::quests; -use crate::ship::ship::{ShipError, ShipEvent}; -use crate::ship::location::{MAX_ROOMS, RoomId}; +use quests; +use maps::Holiday; +use location::{MAX_ROOMS, RoomId}; use maps::room::{Episode, Difficulty, RoomMode}; +#[derive(Error, Debug)] +pub enum RoomError { + #[error("invalid room id {0}")] + Invalid(u32), +} + + #[derive(Clone)] pub struct Rooms([Arc>>; MAX_ROOMS]); + impl Default for Rooms { fn default() -> Rooms { Rooms(core::array::from_fn(|_| Arc::new(RwLock::new(None)))) @@ -33,7 +40,7 @@ impl Rooms { pub async fn add(&self, room_id: RoomId, room: RoomState) -> Result<(), anyhow::Error> { *self.0 .get(room_id.0) - .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))? + .ok_or_else(|| RoomError::Invalid(room_id.0 as u32))? .write() .await = Some(room); Ok(()) @@ -66,14 +73,14 @@ impl Rooms { { let room = self.0 .get(room_id.0) - .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))? + .ok_or_else(|| RoomError::Invalid(room_id.0 as u32))? .read() .await; if let Some(room) = room.as_ref() { Ok(func(room).await) } else { - Err(ShipError::InvalidRoom(room_id.0 as u32).into()) + Err(RoomError::Invalid(room_id.0 as u32).into()) } } @@ -84,7 +91,7 @@ impl Rooms { { let mut room = self.0 .get(room_id.0) - .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))? + .ok_or_else(|| RoomError::Invalid(room_id.0 as u32))? .write() .await; @@ -92,7 +99,7 @@ impl Rooms { Ok(func(room).await) } else { - Err(ShipError::InvalidRoom(room_id.0 as u32).into()) + Err(RoomError::Invalid(room_id.0 as u32).into()) } } @@ -222,8 +229,8 @@ impl RoomState { section_id: SectionID, name: String, password: [u16; 16], - event: ShipEvent, - map_builder: Arc) -> Maps + Send + Sync>>, + event: Holiday, + map_builder: Arc Maps + Send + Sync>>, drop_table_builder: Arc DropTable + Send + Sync>>, ) -> Result { let mode = match mode { @@ -251,7 +258,7 @@ impl RoomState { random_seed: rand::thread_rng().gen(), name, password, - maps: map_builder(mode, event.rare_enemy_event()), + maps: map_builder(mode, event), section_id, drop_table: Box::new(drop_table_builder(episode, difficulty, section_id)), bursting: false, diff --git a/src/bin/login.rs b/src/bin/login.rs index 28d78f0..f4c5335 100644 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -2,7 +2,7 @@ use log::{info}; use entity::gateway::postgres::PostgresGateway; use elseware::login::login::LoginServerState; use elseware::login::character::CharacterServerState; -use elseware::common::interserver::AuthToken; +use networking::interserver::AuthToken; fn main() { let colors = fern::colors::ColoredLevelConfig::new() @@ -38,17 +38,17 @@ fn main() { let login_state = LoginServerState::new(entity_gateway.clone(), charserv_ip); let login_loop = async_std::task::spawn(async move { - elseware::common::mainloop::run_server(login_state, elseware::login::login::LOGIN_PORT).await; + networking::mainloop::run_server(login_state, elseware::login::login::LOGIN_PORT).await; }); let char_state = CharacterServerState::new(entity_gateway, AuthToken(shipgate_token)); let sub_char_state = char_state.clone(); let character_loop = async_std::task::spawn(async move { - elseware::common::mainloop::run_server(sub_char_state, elseware::login::character::CHARACTER_PORT).await; + networking::mainloop::run_server(sub_char_state, elseware::login::character::CHARACTER_PORT).await; }); let inter_character_loop = async_std::task::spawn(async move { - elseware::common::mainloop::run_interserver_listen(char_state, elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_listen(char_state, elseware::login::login::COMMUNICATION_PORT).await; }); info!("[auth/character] starting server"); diff --git a/src/bin/main.rs b/src/bin/main.rs index 23aa720..34e5793 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -1,13 +1,13 @@ use std::net::Ipv4Addr; use log::{info}; -use elseware::common::interserver::AuthToken; +use networking::interserver::AuthToken; use elseware::login::login::LoginServerState; use elseware::login::character::CharacterServerState; use elseware::patch::patch::{PatchServerState, generate_patch_tree, load_config, load_motd}; -use elseware::ship::ship::{ShipServerStateBuilder, ShipEvent}; +use elseware::ship::ship::ShipServerStateBuilder; -#[allow(unused_imports)] +use maps::Holiday; use entity::gateway::{EntityGateway, InMemoryGateway, PostgresGateway}; use entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; use entity::character::NewCharacterEntity; @@ -338,25 +338,25 @@ fn main() { let (patch_file_tree, patch_file_lookup) = generate_patch_tree(patch_config.path.as_str()); let patch_state = PatchServerState::new(patch_file_tree, patch_file_lookup, patch_motd); let patch_loop = async_std::task::spawn(async move { - elseware::common::mainloop::run_server(patch_state, patch_config.port).await; + networking::mainloop::run_server(patch_state, patch_config.port).await; }); info!("[auth] starting server"); let login_state = LoginServerState::new(entity_gateway.clone(), "127.0.0.1".parse().unwrap()); let login_loop = async_std::task::spawn(async move { - elseware::common::mainloop::run_server(login_state, elseware::login::login::LOGIN_PORT).await; + networking::mainloop::run_server(login_state, elseware::login::login::LOGIN_PORT).await; }); info!("[character] starting server"); let char_state = CharacterServerState::new(entity_gateway.clone(), AuthToken("".into())); let sub_char_state = char_state.clone(); let character_loop = async_std::task::spawn(async move { - elseware::common::mainloop::run_server(sub_char_state, elseware::login::character::CHARACTER_PORT).await; + networking::mainloop::run_server(sub_char_state, elseware::login::character::CHARACTER_PORT).await; }); let sub_char_state = char_state.clone(); let inter_character_loop = async_std::task::spawn(async move { - elseware::common::mainloop::run_interserver_listen(sub_char_state, elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_listen(sub_char_state, elseware::login::login::COMMUNICATION_PORT).await; }); info!("[ship] starting servers"); @@ -364,32 +364,32 @@ fn main() { .name("US/Sona-Nyl".into()) .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT) - .event(ShipEvent::Halloween) + .event(Holiday::Halloween) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); let ship_loop1 = async_std::task::spawn(async move { - elseware::common::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT).await; + networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT).await; }); let sub_ship_state = ship_state.clone(); let inter_ship_loop1 = async_std::task::spawn(async move { - elseware::common::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; }); let ship_state = ShipServerStateBuilder::default() .name("EU/Dylath-Leen".into()) .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT+2000) - .event(ShipEvent::Christmas) + .event(Holiday::Christmas) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); let ship_loop2 = async_std::task::spawn(async move { - elseware::common::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT+2000).await; + networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT+2000).await; }); let sub_ship_state = ship_state.clone(); let inter_ship_loop2 = async_std::task::spawn(async move { - elseware::common::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; }); let ship_state = ShipServerStateBuilder::default() @@ -400,11 +400,11 @@ fn main() { .build(); let sub_ship_state = ship_state.clone(); let ship_loop3 = async_std::task::spawn(async move { - elseware::common::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT+3000).await; + networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT+3000).await; }); let sub_ship_state = ship_state.clone(); let inter_ship_loop3 = async_std::task::spawn(async move { - elseware::common::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; }); futures::future::join_all(vec![patch_loop, login_loop, character_loop, inter_character_loop, diff --git a/src/bin/patch.rs b/src/bin/patch.rs index 6716391..fc9eff8 100644 --- a/src/bin/patch.rs +++ b/src/bin/patch.rs @@ -1,5 +1,5 @@ use elseware::patch::patch::{PatchServerState, generate_patch_tree, load_config_env, load_motd}; -use log::{info}; +use log::info; fn main() { info!("[patch] starting server"); @@ -9,7 +9,7 @@ fn main() { let patch_state = PatchServerState::new(patch_file_tree, patch_file_lookup, patch_motd); let patch_loop = async_std::task::spawn(async move { - elseware::common::mainloop::run_server(patch_state, patch_config.port).await; + networking::mainloop::run_server(patch_state, patch_config.port).await; }); async_std::task::block_on(patch_loop); diff --git a/src/bin/ship.rs b/src/bin/ship.rs index 0f289b7..c021601 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -1,7 +1,7 @@ -use log::{info}; +use log::info; use entity::gateway::postgres::PostgresGateway; use elseware::ship::ship::ShipServerStateBuilder; -use elseware::common::interserver::AuthToken; +use networking::interserver::AuthToken; fn main() { let colors = fern::colors::ColoredLevelConfig::new() @@ -49,10 +49,10 @@ fn main() { let sub_ship_state = ship_state.clone(); let ship_loop = async_std::task::spawn(async move { - elseware::common::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT).await; + networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT).await; }); let inter_ship_loop = async_std::task::spawn(async move { - elseware::common::mainloop::run_interserver_connect(ship_state, shipgate_ip, elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_connect(ship_state, shipgate_ip, elseware::login::login::COMMUNICATION_PORT).await; }); info!("[auth/character] starting server"); diff --git a/src/common/mod.rs b/src/common/mod.rs deleted file mode 100644 index c8adde9..0000000 --- a/src/common/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -pub mod cipherkeys; -pub mod serverstate; -pub mod mainloop; -pub mod interserver; - -// https://www.reddit.com/r/rust/comments/33xhhu/how_to_create_an_array_of_structs_that_havent/ -#[macro_export] -macro_rules! init_array( - ($ty:ty, $len:expr, $val:expr) => ( - { - let mut array: [$ty; $len] = unsafe { std::mem::uninitialized() }; - for i in array.iter_mut() { - unsafe { ::std::ptr::write(i, $val); } - } - array - } - ) -); diff --git a/src/lib.rs b/src/lib.rs index 3802b3c..f194399 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,11 +5,10 @@ #![feature(try_blocks)] #![feature(test)] #![feature(error_generic_member_access)] -#![feature(lazy_cell)] extern crate test; -pub mod common; +//pub mod common; //pub mod entity; pub mod patch; pub mod login; diff --git a/src/login/character.rs b/src/login/character.rs index ef74730..6529f3d 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -15,9 +15,9 @@ use libpso::crypto::bb::PSOBBCipher; use libpso::character::character; use entity::item; -use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; -use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; -use crate::common::interserver::{ServerId, InterserverActor, LoginMessage, ShipMessage, Ship}; +use networking::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; +use networking::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; +use networking::interserver::{ServerId, InterserverActor, LoginMessage, ShipMessage, Ship}; use stats::leveltable::LEVEL_TABLE; use libpso::{utf8_to_array, utf8_to_utf16_array}; @@ -32,10 +32,11 @@ use entity::item::mag::Mag; use entity::character::{CharacterEntity, NewCharacterEntity, CharacterClass, TechLevel}; use crate::login::login::{get_login_status}; -use crate::common::interserver::AuthToken; +use networking::interserver::AuthToken; + +use pktbuilder::ship::SHIP_MENU_ID; pub const CHARACTER_PORT: u16 = 12001; -pub const SHIP_MENU_ID: u32 = 1; #[derive(thiserror::Error, Debug)] pub enum CharacterError { diff --git a/src/login/login.rs b/src/login/login.rs index 4b1433c..cdc32d9 100644 --- a/src/login/login.rs +++ b/src/login/login.rs @@ -11,8 +11,8 @@ use libpso::{PacketParseError, PSOPacket}; use libpso::crypto::bb::PSOBBCipher; use libpso::util::array_to_utf8; -use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; -use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; +use networking::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; +use networking::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; use entity::gateway::EntityGateway; use entity::account::{UserAccountEntity}; diff --git a/src/patch/patch.rs b/src/patch/patch.rs index 26441f8..565530d 100644 --- a/src/patch/patch.rs +++ b/src/patch/patch.rs @@ -11,8 +11,8 @@ use libpso::crypto::pc::PSOPCCipher; use ron::de::from_str; use serde::Deserialize; -use crate::common::mainloop::{NetworkError}; -use crate::common::serverstate::{RecvServerPacket, SendServerPacket, ServerState, OnConnect, ClientId}; +use networking::mainloop::{NetworkError}; +use networking::serverstate::{RecvServerPacket, SendServerPacket, ServerState, OnConnect, ClientId}; #[derive(Debug)] pub enum PatchError { diff --git a/src/ship/chatcommand.rs b/src/ship/chatcommand.rs index 7d2c643..7799e17 100644 --- a/src/ship/chatcommand.rs +++ b/src/ship/chatcommand.rs @@ -1,11 +1,11 @@ use libpso::packet::ship::PlayerChat; use entity::gateway::EntityGateway; -use crate::common::serverstate::ClientId; +use networking::serverstate::ClientId; use crate::ship::ship::{ShipServerState, SendShipPacket}; -use crate::ship::client::Clients; -use crate::ship::items::state::ItemState; +use client::Clients; +use items::state::ItemState; use entity::item::{BankName, BankIdentifier}; -use crate::ship::packet::builder::message::bank_item_list; +use pktbuilder::message::bank_item_list; async fn default_bank<'a, EG>(id: ClientId, entity_gateway: &mut EG, diff --git a/src/ship/drops/drop_table.rs b/src/ship/drops/drop_table.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/ship/mod.rs b/src/ship/mod.rs index d769c38..f6ada33 100644 --- a/src/ship/mod.rs +++ b/src/ship/mod.rs @@ -1,16 +1,16 @@ #[allow(clippy::module_inception)] pub mod ship; -pub mod location; -pub mod character; -pub mod client; -pub mod room; -pub mod items; +//pub mod location; +//pub mod character; +//pub mod client; +//pub mod room; +//pub mod items; //pub mod item_stats; //pub mod map; //pub mod monster; -pub mod drops; +//pub mod drops; pub mod packet; -pub mod quests; +//pub mod quests; //pub mod shops; -pub mod trade; +//pub mod trade; pub mod chatcommand; diff --git a/src/ship/monster.rs b/src/ship/monster.rs deleted file mode 100644 index 1bdb5b7..0000000 --- a/src/ship/monster.rs +++ /dev/null @@ -1,212 +0,0 @@ -#![allow(dead_code)] -use std::collections::HashMap; -use std::fs::File; -use std::io::Read; -use std::path::PathBuf; -use serde::{Serialize, Deserialize}; -use crate::ship::room::{Difficulty, Episode, RoomMode}; - - -#[derive(Debug)] -pub enum MonsterParseError { - UnknownMonster(String), -} - -pub struct MonsterStatError; - -#[derive(Debug, Serialize, Deserialize, Copy, Clone, Hash, Eq, PartialEq, enum_utils::FromStr, derive_more::Display)] -pub enum MonsterType { - Hildebear, - Hildeblue, - Mothmant, - Monest, - RagRappy, - AlRappy, - SavageWolf, - BarbarousWolf, - Booma, - Gobooma, - Gigobooma, - GrassAssassin, - PoisonLily, - NarLily, - NanoDragon, - EvilShark, - PalShark, - GuilShark, - PofuillySlime, - PouillySlime, - PanArms, - Hidoom, - Migium, - Dubchic, - Garanz, - SinowBeat, - SinowGold, - Canadine, - Canane, - RingCanadine, - Delsaber, - ChaosSorcerer, - BeeR, - BeeL, - DarkGunner, - DeathGunner, - ChaosBringer, - DarkBelra, - Claw, - Bulk, - Bulclaw, - Dimenian, - LaDimenian, - SoDimenian, - Dragon, - DeRolLe, - DeRolLeBody, - DeRolLeMine, - VolOptPartA, - VolOptPillar, - VolOptMonitor, - VolOptAmp, - VolOptCore, - VolOptUnused, - VolOpt, - VolOptTrap, - DarkFalz, - DarkFalz1, - DarkFalz2, - DarkFalz3, - Darvant, - UltDarvant, - Dubwitch, - Gillchic, - EventRappy, - Merillia, - Meriltas, - Gee, - GiGue, - Mericarol, - Merikle, - Mericus, - UlGibbon, - ZolGibbon, - Gibbles, - SinowBerill, - SinowSpigell, - Dolmolm, - Dolmdarl, - Morfos, - Recobox, - Recon, - SinowZoa, - SinowZele, - Deldepth, - Delbiter, - BarbaRay, - PigRay, - GolDragon, - GalGryphon, - OlgaFlow, - OlgaFlow1, - OlgaFlow2, - Gael, - Giel, - StRappy, - HalloRappy, - EasterRappy, - LoveRappy, - IllGill, - DelLily, - Epsilon, - Epsiguard, - Boota, - ZeBoota, - BaBoota, - SandRappyCrater, - SandRappyDesert, - ZuCrater, - PazuzuCrater, - Astark, - SatelliteLizardCrater, - YowieCrater, - Dorphon, - DorphonEclair, - Goran, - GoranDetonator, - PyroGoran, - DelRappyCrater, - DelRappyDesert, - MerissaA, - MerissaAA, - ZuDesert, - PazuzuDesert, - SatelliteLizardDesert, - YowieDesert, - Girtablulu, - SaintMillion, - Shambertin, - Kondrieu, -} - - -#[derive(serde::Deserialize, Debug)] -pub struct MonsterStats { - pub atp: u16, - pub mst: u16, - pub evp: u16, - pub hp: u16, - pub dfp: u16, - pub ata: u16, - pub lck: u16, - pub esp: u16, - pub exp: u32, -} - -fn load_battle_param(filename: &str) -> HashMap { - let mut path = PathBuf::from("data/battle_param/"); - path.push(filename); - - let mut f = File::open(path).unwrap(); - let mut s = String::new(); - f.read_to_string(&mut s).unwrap(); - toml::from_str::>(s.as_str()).unwrap() - .into_iter() - .map(|(monster_name, stats)| { - (monster_name.parse().unwrap(), stats) - }).collect() -} - -pub fn load_monster_stats_table(mode: &RoomMode) -> Result, MonsterStatError> { - match mode { - RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep1_multi_normal.toml")), - RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep1_multi_hard.toml")), - RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep1_multi_veryhard.toml")), - RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep1_multi_ultimate.toml")), - - RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep2_multi_normal.toml")), - RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep2_multi_hard.toml")), - RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep2_multi_veryhard.toml")), - RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep2_multi_ultimate.toml")), - - RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep4_multi_normal.toml")), - RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep4_multi_hard.toml")), - RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep4_multi_veryhard.toml")), - RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep4_multi_ultimate.toml")), - - RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep1_solo_normal.toml")), - RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep1_solo_hard.toml")), - RoomMode::Single {episode: Episode::One, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep1_solo_veryhard.toml")), - RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep1_solo_ultimate.toml")), - - RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep2_solo_normal.toml")), - RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep2_solo_hard.toml")), - RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep2_solo_veryhard.toml")), - RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep2_solo_ultimate.toml")), - - RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep4_solo_normal.toml")), - RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep4_solo_hard.toml")), - RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep4_solo_veryhard.toml")), - RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep4_solo_ultimate.toml")), - _ => Err(MonsterStatError), - } -} diff --git a/src/ship/packet/handler/auth.rs b/src/ship/packet/handler/auth.rs index bd0c846..915da68 100644 --- a/src/ship/packet/handler/auth.rs +++ b/src/ship/packet/handler/auth.rs @@ -1,11 +1,11 @@ use libpso::packet::login::{Login, LoginResponse, AccountStatus, Session}; use libpso::packet::ship::*; -use crate::common::serverstate::ClientId; +use networking::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, ShipError, ClientState, Clients}; use crate::login::login::get_login_status; use entity::gateway::EntityGateway; -use crate::ship::items::state::ItemState; -use crate::common::interserver::ShipMessage; +use items::state::ItemState; +use networking::interserver::ShipMessage; #[allow(clippy::too_many_arguments)] pub async fn validate_login(id: ClientId, diff --git a/src/ship/packet/handler/communication.rs b/src/ship/packet/handler/communication.rs index 2f7ef43..3982efc 100644 --- a/src/ship/packet/handler/communication.rs +++ b/src/ship/packet/handler/communication.rs @@ -1,7 +1,7 @@ use libpso::packet::ship::*; -use crate::common::serverstate::ClientId; +use networking::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, Clients}; -use crate::ship::location::{ClientLocation}; +use location::{ClientLocation}; use entity::gateway::EntityGateway; use futures::future::join_all; diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index dea6911..090d77d 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/src/ship/packet/handler/direct_message.rs @@ -4,21 +4,21 @@ use rand::seq::SliceRandom; use libpso::packet::ship::*; use libpso::packet::messages::*; use stats::leveltable::LEVEL_TABLE; -use crate::common::serverstate::ClientId; +use networking::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, ShipError, Clients, ItemShops}; -use crate::ship::location::ClientLocation; -use crate::ship::drops::ItemDrop; -use crate::ship::room::Rooms; -use crate::ship::items::ClientItemId; +use location::ClientLocation; +use drops::ItemDrop; +use room::Rooms; +use items::ClientItemId; use entity::gateway::EntityGateway; use entity::item; use libpso::utf8_to_utf16_array; -use crate::ship::packet::builder; +use pktbuilder as builder; use shops::{ShopItem, ToolShopItem, ArmorShopItem}; -use crate::ship::items::state::{ItemState, ItemStateError}; -use crate::ship::items::floor::{FloorType, FloorItemDetail}; -use crate::ship::items::actions::TriggerCreateItem; -use crate::ship::items::tasks::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, enemy_drops_item, box_drops_item, take_meseta, apply_modifier}; +use items::state::{ItemState, ItemStateError}; +use items::floor::{FloorType, FloorItemDetail}; +use items::actions::TriggerCreateItem; +use items::tasks::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, enemy_drops_item, box_drops_item, take_meseta, apply_modifier}; const BANK_ACTION_DEPOSIT: u8 = 0; const BANK_ACTION_WITHDRAW: u8 = 1; @@ -122,7 +122,7 @@ where })).await?; let floor_item = enemy_drops_item(item_state, entity_gateway, character_id, room_entity_id, monster.monster, item_drop).await?; - let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, &floor_item)?; + let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, &floor_item); item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))); } @@ -149,10 +149,10 @@ where let mut item_state = item_state.clone(); Box::pin(async move { let (item, floor_type) = item_state.get_floor_item(&client.character.id, &ClientItemId(pickup_item.item_id)).await?; - let remove_item = builder::message::remove_item_from_floor(area_client, &item)?; + let remove_item = builder::message::remove_item_from_floor(area_client, &item); let create_item = match &item.item { - FloorItemDetail::Individual(individual_floor_item) => Some(builder::message::create_individual_item(area_client, item.item_id, individual_floor_item)?), - FloorItemDetail::Stacked(stacked_floor_item) => Some(builder::message::create_stacked_item(area_client, item.item_id, &stacked_floor_item.tool, stacked_floor_item.count())?), + FloorItemDetail::Individual(individual_floor_item) => Some(builder::message::create_individual_item(area_client, item.item_id, individual_floor_item)), + FloorItemDetail::Stacked(stacked_floor_item) => Some(builder::message::create_stacked_item(area_client, item.item_id, &stacked_floor_item.tool, stacked_floor_item.count())), FloorItemDetail::Meseta(_) => None, }; @@ -234,7 +234,7 @@ where })).await?; let floor_item = box_drops_item(item_state, entity_gateway, character_id, room_entity_id, item_drop).await?; //let floor_item = enemy_drops_item(item_state, &mut entity_gateway, client.character.id, item_drop).await?; - let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, &floor_item)?; + let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, &floor_item); item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))) } @@ -293,7 +293,7 @@ where } else { let item_added_to_inventory = withdraw_item(&mut item_state, &mut entity_gateway, &client.character, &ClientItemId(bank_interaction.item_id), bank_interaction.item_amount as u32).await?; - let item_created = builder::message::create_withdrawn_inventory_item2(area_client, &item_added_to_inventory)?; + let item_created = builder::message::create_withdrawn_inventory_item2(area_client, &item_added_to_inventory); vec![SendShipPacket::Message(Message::new(GameMessage::CreateItem(item_created)))] } }, @@ -440,7 +440,7 @@ where _ => {} } } - Ok::<_, anyhow::Error>(builder::message::create_withdrawn_inventory_item(area_client, &inventory_item)?) + Ok::<_, anyhow::Error>(builder::message::create_withdrawn_inventory_item(area_client, &inventory_item)) })}).await??; let other_clients_in_area = client_location.get_client_neighbors(id).await?; @@ -503,7 +503,7 @@ where }); take_meseta(&mut item_state, &mut entity_gateway, &client.character.id, item::Meseta(100)).await?; - Ok::<_, anyhow::Error>(builder::message::tek_preview(ClientItemId(tek_request.item_id), &weapon)?) + Ok::<_, anyhow::Error>(builder::message::tek_preview(ClientItemId(tek_request.item_id), &weapon)) })}).await??; @@ -539,7 +539,7 @@ where }; let weapon = apply_modifier(&mut item_state, &mut entity_gateway, &client.character, item_id, item::ItemModifier::WeaponModifier(modifier)).await?; - let create_item_pkt = builder::message::create_individual_item(area_client, item_id, &weapon)?; + let create_item_pkt = builder::message::create_individual_item(area_client, item_id, &weapon); Ok(neighbors.into_iter() .map(move |c| { diff --git a/src/ship/packet/handler/lobby.rs b/src/ship/packet/handler/lobby.rs index d085cc6..3033091 100644 --- a/src/ship/packet/handler/lobby.rs +++ b/src/ship/packet/handler/lobby.rs @@ -1,12 +1,14 @@ use libpso::packet::ship::*; -use crate::common::serverstate::ClientId; +use networking::serverstate::ClientId; use stats::leveltable::LEVEL_TABLE; -use crate::ship::ship::{SendShipPacket, ShipError, Clients, ShipEvent}; -use crate::ship::room::Rooms; -use crate::ship::character::{FullCharacterBytesBuilder}; -use crate::ship::location::{ClientLocation, LobbyId, RoomLobby, ClientLocationError, RoomId}; -use crate::ship::packet; -use crate::ship::items::state::ItemState; +use crate::ship::ship::{SendShipPacket, ShipError}; +use maps::Holiday; +use client::Clients; +use room::Rooms; +use pktbuilder::character::FullCharacterBytesBuilder; +use location::{ClientLocation, LobbyId, RoomLobby, ClientLocationError, RoomId}; +//use pktbuilder; +use items::state::ItemState; use entity::gateway::EntityGateway; use entity::room::RoomNote; use maps::area::MapArea; @@ -57,11 +59,11 @@ pub async fn send_player_to_lobby(id: ClientId, client_location: &mut ClientLocation, clients: &Clients, item_state: &ItemState, - event: ShipEvent) + event: Holiday) -> Result, anyhow::Error> { let lobby = client_location.add_client_to_next_available_lobby(id, LobbyId(0)).await.map_err(|_| ShipError::TooManyClients)?; - let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_state, event).await?; - let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_state, event).await?; + let join_lobby = pktbuilder::lobby::join_lobby(id, lobby, client_location, clients, item_state, event).await?; + let addto = pktbuilder::lobby::add_to_lobby(id, lobby, client_location, clients, item_state, event).await?; let neighbors = client_location.get_client_neighbors(id).await.unwrap(); Ok(vec![(id, SendShipPacket::JoinLobby(join_lobby))] .into_iter() @@ -77,7 +79,7 @@ pub async fn change_lobby(id: ClientId, item_state: &mut ItemState, rooms: &Rooms, entity_gateway: &mut EG, - event: ShipEvent) + event: Holiday) -> Result, anyhow::Error> where EG: EntityGateway + Clone + 'static, @@ -111,7 +113,7 @@ where })}).await??; }, } - let leave_lobby = packet::builder::lobby::remove_from_lobby(id, client_location).await?; + let leave_lobby = pktbuilder::lobby::remove_from_lobby(id, client_location).await?; let old_neighbors = client_location.get_client_neighbors(id).await.unwrap(); let mut lobby = LobbyId(requested_lobby as usize); if client_location.add_client_to_lobby(id, lobby).await.is_err() { @@ -131,8 +133,8 @@ where Box::pin(async move { item_state.load_character(&mut entity_gateway, &client.character).await })}).await??; - let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_state, event).await?; - let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_state, event).await?; + let join_lobby = pktbuilder::lobby::join_lobby(id, lobby, client_location, clients, item_state, event).await?; + let addto = pktbuilder::lobby::add_to_lobby(id, lobby, client_location, clients, item_state, event).await?; let neighbors = client_location.get_client_neighbors(id).await?; Ok(vec![(id, SendShipPacket::JoinLobby(join_lobby))] .into_iter() diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index 497f2d9..ca731c9 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -2,15 +2,16 @@ use libpso::packet::ship::*; use libpso::packet::messages::*; use entity::gateway::EntityGateway; use entity::item::Meseta; -use crate::common::serverstate::ClientId; +use networking::serverstate::ClientId; use stats::leveltable::LEVEL_TABLE; -use crate::ship::ship::{SendShipPacket, ShipError, Clients, ItemDropLocation}; -use crate::ship::room::Rooms; -use crate::ship::location::{ClientLocation, ClientLocationError}; -use crate::ship::items::ClientItemId; -use crate::ship::packet::builder; -use crate::ship::items::state::ItemState; -use crate::ship::items::tasks::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item, sort_inventory, use_item, feed_mag, sell_item, take_meseta, floor_item_limit_reached}; +use crate::ship::ship::{SendShipPacket, ShipError}; +use client::{Clients, ItemDropLocation}; +use ::room::Rooms; +use location::{ClientLocation, ClientLocationError}; +use items::ClientItemId; +use pktbuilder as builder; +use items::state::ItemState; +use items::tasks::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item, sort_inventory, use_item, feed_mag, sell_item, take_meseta, floor_item_limit_reached}; pub async fn request_exp(id: ClientId, request_exp: RequestExp, @@ -162,7 +163,7 @@ where drop_meseta(&mut item_state, &mut entity_gateway, &client.character, drop_location.map_area, (drop_location.x, drop_location.z), no_longer_has_item.amount).await })}).await??; - let dropped_meseta_pkt = builder::message::drop_split_meseta_stack(area_client, &dropped_meseta)?; + let dropped_meseta_pkt = builder::message::drop_split_meseta_stack(area_client, &dropped_meseta); let no_longer_has_meseta_pkt = builder::message::player_no_longer_has_meseta(area_client, no_longer_has_item.amount); let clients_in_area = client_location.get_clients_in_room(room_id).await.map_err(|err| -> ClientLocationError { err.into() })?; @@ -198,7 +199,7 @@ where no_longer_has_item.amount) .await })}).await??; - let dropped_item_pkt = builder::message::drop_split_stack(area_client, &dropped_item)?; + let dropped_item_pkt = builder::message::drop_split_stack(area_client, &dropped_item); let clients_in_area = client_location.get_clients_in_room(room_id).await.map_err(|err| -> ClientLocationError { err.into() })?; Ok(clients_in_area.into_iter() @@ -348,6 +349,15 @@ where })}).await?? .into_iter() .flat_map(move |pkt| { + let pkt = match pkt { + items::actions::CreateItem::Individual(area_client, item_id, item_detail) => { + builder::message::create_individual_item(area_client, item_id, &item_detail) + }, + items::actions::CreateItem::Stacked(area_client, item_id, tool, amount) => { + builder::message::create_stacked_item(area_client, item_id, &tool, amount) + } + }; + let pkt = SendShipPacket::Message(Message::new(GameMessage::CreateItem(pkt))); let player_use_tool = player_use_tool.clone(); neighbors.clone().map(move |client| { vec![(client.client, SendShipPacket::Message(Message::new(GameMessage::PlayerUseItem(player_use_tool.clone())))), (client.client, pkt.clone())] diff --git a/src/ship/packet/handler/quest.rs b/src/ship/packet/handler/quest.rs index b219684..6193530 100644 --- a/src/ship/packet/handler/quest.rs +++ b/src/ship/packet/handler/quest.rs @@ -1,12 +1,14 @@ use std::io::{Cursor, Read, Seek, SeekFrom}; use futures::stream::{FuturesOrdered, StreamExt}; use libpso::packet::ship::*; -use crate::common::serverstate::ClientId; -use crate::ship::ship::{SendShipPacket, ShipError, Clients, ShipEvent}; -use crate::ship::room::Rooms; +use networking::serverstate::ClientId; +use crate::ship::ship::{SendShipPacket, ShipError}; +use client::Clients; +use maps::Holiday; +use room::Rooms; use maps::enemy::RareMonsterAppearTable; -use crate::ship::location::{ClientLocation}; -use crate::ship::packet::builder::quest; +use location::{ClientLocation}; +use pktbuilder::quest; use libpso::util::array_to_utf8; enum QuestFileType { @@ -97,7 +99,7 @@ pub async fn player_chose_quest(id: ClientId, clients: &Clients, client_location: &ClientLocation, rooms: &Rooms, - event: ShipEvent) + event: Holiday) -> Result, anyhow::Error> { let room_id = client_location.get_room(id).await?; @@ -118,7 +120,7 @@ pub async fn player_chose_quest(id: ClientId, .clone(); let rare_monster_table = RareMonsterAppearTable::new(room.mode.episode()); - room.maps.set_quest_data(quest.enemies.clone(), quest.objects.clone(), &rare_monster_table, event.rare_enemy_event()); + room.maps.set_quest_data(quest.enemies.clone(), quest.objects.clone(), &rare_monster_table, event); room.map_areas = quest.map_areas.clone(); let bin = quest::quest_header(&questmenuselect, &quest.bin_blob, "bin"); diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 9fc8ccc..26e98b4 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -5,20 +5,21 @@ use async_std::sync::Arc; use libpso::packet::ship::*; use libpso::packet::messages::*; -use crate::common::serverstate::ClientId; +use networking::serverstate::ClientId; use stats::leveltable::LEVEL_TABLE; use entity::gateway::EntityGateway; use entity::character::SectionID; use entity::room::{NewRoomEntity, RoomEntityMode, RoomNote}; -use crate::ship::drops::DropTable; -use crate::ship::ship::{SendShipPacket, Clients, ShipEvent}; -use crate::ship::room::{Rooms, RoomState, RoomCreationError}; +use drops::DropTable; +use crate::ship::ship::SendShipPacket; +use client::Clients; +use room::{Rooms, RoomState, RoomCreationError}; +use maps::Holiday; use maps::room::{Episode, Difficulty, RoomMode}; -use maps::enemy::RareEnemyEvent; use maps::maps::Maps; -use crate::ship::location::{ClientLocation, RoomId, RoomLobby, GetAreaError}; -use crate::ship::packet::builder; -use crate::ship::items::state::ItemState; +use location::{ClientLocation, RoomId, RoomLobby, GetAreaError}; +use pktbuilder as builder; +use items::state::ItemState; #[allow(clippy::too_many_arguments)] pub async fn create_room(id: ClientId, @@ -28,9 +29,9 @@ pub async fn create_room(id: ClientId, clients: &Clients, item_state: &mut ItemState, rooms: &Rooms, - map_builder: Arc) -> Maps + Send + Sync>>, + map_builder: Arc Maps + Send + Sync>>, drop_table_builder: Arc DropTable + Send + Sync>>, - event: ShipEvent) + event: Holiday) -> Result, anyhow::Error> where EG: EntityGateway + Clone + 'static, @@ -136,7 +137,7 @@ pub async fn join_room(id: ClientId, clients: &Clients, item_state: &mut ItemState, rooms: &Rooms, - event: ShipEvent) + event: Holiday) -> Result, anyhow::Error> where EG: EntityGateway + Clone + 'static, diff --git a/src/ship/packet/handler/settings.rs b/src/ship/packet/handler/settings.rs index c8ebd52..4bd665d 100644 --- a/src/ship/packet/handler/settings.rs +++ b/src/ship/packet/handler/settings.rs @@ -1,5 +1,5 @@ use libpso::packet::ship::*; -use crate::common::serverstate::ClientId; +use networking::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, Clients}; use entity::gateway::EntityGateway; diff --git a/src/ship/packet/handler/ship.rs b/src/ship/packet/handler/ship.rs index a63ebdf..762e73f 100644 --- a/src/ship/packet/handler/ship.rs +++ b/src/ship/packet/handler/ship.rs @@ -1,10 +1,10 @@ use async_std::sync::{Arc, RwLock}; use libpso::packet::ship::*; use libpso::packet::login::RedirectClient; -use crate::common::serverstate::ClientId; -use crate::common::interserver::Ship; +use networking::serverstate::ClientId; +use networking::interserver::Ship; use crate::ship::ship::{SendShipPacket, ShipError}; -use crate::ship::packet::builder; +use pktbuilder as builder; pub async fn ship_list(id: ClientId, ship_list: &Arc>>) -> Vec<(ClientId, SendShipPacket)> { let ship_list = ship_list diff --git a/src/ship/packet/handler/trade.rs b/src/ship/packet/handler/trade.rs index f3128d0..8da8f38 100644 --- a/src/ship/packet/handler/trade.rs +++ b/src/ship/packet/handler/trade.rs @@ -1,19 +1,19 @@ use std::convert::TryInto; use libpso::packet::ship::*; use libpso::packet::messages::*; -use crate::common::serverstate::ClientId; +use networking::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, ShipError, Clients}; -use crate::ship::location::{ClientLocation}; -use crate::ship::items::ClientItemId; -use crate::ship::items::state::{ItemState, ItemStateError}; -use crate::ship::items::inventory::InventoryItemDetail; -use crate::ship::trade::{TradeItem, TradeState, TradeStatus}; +use location::{ClientLocation}; +use items::ClientItemId; +use items::state::{ItemState, ItemStateError}; +use items::inventory::InventoryItemDetail; +use items::trade::TradeItem; use entity::gateway::EntityGateway; -use crate::ship::packet::builder; -use crate::ship::items::tasks::trade_items; -use crate::ship::location::{AreaClient, RoomId}; +use pktbuilder as builder; +use items::tasks::trade_items; +use location::{AreaClient, RoomId}; use entity::item::Meseta; -use crate::ship::trade::ClientTradeState; +use trade::{ClientTradeState, TradeState, TradeStatus}; pub const MESETA_ITEM_ID: ClientItemId = ClientItemId(0xFFFFFF01); pub const OTHER_MESETA_ITEM_ID: ClientItemId = ClientItemId(0xFFFFFFFF); @@ -450,8 +450,8 @@ where enum TradeReady/*<'a>*/ { OnePlayer, BothPlayers(RoomId, - (AreaClient, crate::ship::trade::ClientTradeState), - (AreaClient, crate::ship::trade::ClientTradeState)), + (AreaClient, ClientTradeState), + (AreaClient, ClientTradeState)), //(AreaClient, &'a crate::ship::ship::ClientState, crate::ship::trade::ClientTradeState), //(AreaClient, &'a crate::ship::ship::ClientState, crate::ship::trade::ClientTradeState)), } @@ -527,10 +527,10 @@ where .map(|(client, item)| { match item.item { InventoryItemDetail::Individual(individual_item) => { - GameMessage::CreateItem(builder::message::create_individual_item(client, item.item_id, &individual_item).unwrap()) + GameMessage::CreateItem(builder::message::create_individual_item(client, item.item_id, &individual_item)) }, InventoryItemDetail::Stacked(stacked_item) => { - GameMessage::CreateItem(builder::message::create_stacked_item(client, item.item_id, &stacked_item.tool, stacked_item.count()).unwrap()) + GameMessage::CreateItem(builder::message::create_stacked_item(client, item.item_id, &stacked_item.tool, stacked_item.count())) } } }); diff --git a/src/ship/packet/mod.rs b/src/ship/packet/mod.rs index 5b46ce1..9b5f908 100644 --- a/src/ship/packet/mod.rs +++ b/src/ship/packet/mod.rs @@ -1,2 +1,2 @@ -pub mod builder; +//pub mod builder; pub mod handler; diff --git a/src/ship/ship.rs b/src/ship/ship.rs index a384555..e4764e0 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -14,31 +14,29 @@ use libpso::{PacketParseError, PSOPacket}; use libpso::crypto::bb::PSOBBCipher; use libpso::packet::ship::{BLOCK_MENU_ID, ROOM_MENU_ID}; -use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; -use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; -use crate::common::interserver::{AuthToken, Ship, ServerId, InterserverActor, LoginMessage, ShipMessage}; -use crate::login::character::SHIP_MENU_ID; +use networking::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; +use networking::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; +use networking::interserver::{AuthToken, Ship, ServerId, InterserverActor, LoginMessage, ShipMessage}; +use pktbuilder::ship::SHIP_MENU_ID; use entity::gateway::{EntityGateway, GatewayError}; use entity::character::SectionID; use entity::room::RoomNote; -use crate::ship::location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; -use crate::ship::drops::DropTable; -use crate::ship::items; -use crate::ship::room; +use location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; +use drops::DropTable; +use items; +use room; +use maps::Holiday; use maps::area::MapAreaError; use maps::maps::{Maps, MapsError, generate_free_roam_maps}; -use maps::enemy::RareEnemyEvent; use crate::ship::packet::handler; use shops::{WeaponShop, ToolShop, ArmorShop}; -use crate::ship::trade::TradeState; +use trade::TradeState; use crate::ship::chatcommand; +use pktbuilder::quest::{QUEST_CATEGORY_MENU_ID, QUEST_SELECT_MENU_ID}; -// TODO: remove once stuff settles down -pub use crate::ship::client::*; +pub use client::{Clients, ClientState}; pub const SHIP_PORT: u16 = 23423; -pub const QUEST_CATEGORY_MENU_ID: u32 = 0xA2; -pub const QUEST_SELECT_MENU_ID: u32 = 0xA3; #[derive(Error, Debug)] @@ -100,7 +98,7 @@ pub enum ShipError { #[error("trade error {0}")] TradeError(#[from] crate::ship::packet::handler::trade::TradeError), #[error("trade state error {0}")] - TradeStateError(#[from] crate::ship::trade::TradeStateError), + TradeStateError(#[from] trade::TradeStateError), #[error("message error {0}")] MessageError(#[from] crate::ship::packet::handler::direct_message::MessageError), #[error("room creation error {0}")] @@ -117,69 +115,6 @@ impl> From for ShipError { } */ -#[derive(Clone, Copy)] -pub enum ShipEvent { - None, - Christmas, - Valentines, - Easter, - Halloween, - Sonic, - NewYear, - Summer, - White, - Wedding, - Fall, - Spring, - Summer2, - Spring2, -} - - -impl From for u32 { - fn from(other: ShipEvent) -> u32 { - u16::from(other) as u32 - } -} - -impl From for u16 { - fn from(other: ShipEvent) -> u16 { - u8::from(other) as u16 - } -} - -impl From for u8 { - fn from(other: ShipEvent) -> u8 { - match other { - ShipEvent::None => 0, - ShipEvent::Christmas => 1, - ShipEvent::Valentines => 3, - ShipEvent::Easter => 4, - ShipEvent::Halloween => 5, - ShipEvent::Sonic => 6, - ShipEvent::NewYear => 7, - ShipEvent::Summer => 8, - ShipEvent::White => 9, - ShipEvent::Wedding => 10, - ShipEvent::Fall => 11, - ShipEvent::Spring => 12, - ShipEvent::Summer2 => 13, - ShipEvent::Spring2 => 14, - } - } -} - -impl ShipEvent { - pub fn rare_enemy_event(&self) -> Option { - match self { - ShipEvent::Easter => Some(RareEnemyEvent::Easter), - ShipEvent::Halloween => Some(RareEnemyEvent::Halloween), - ShipEvent::Christmas => Some(RareEnemyEvent::Christmas), - _ => None, - } - } -} - #[derive(Debug)] @@ -393,8 +328,8 @@ pub struct ShipServerStateBuilder { ip: Option, port: Option, auth_token: Option, - event: Option, - map_builder: Option) -> Maps + Send + Sync>>, + event: Option, + map_builder: Option Maps + Send + Sync>>, drop_table_builder: Option DropTable + Send + Sync>>, num_blocks: usize, } @@ -447,13 +382,13 @@ impl ShipServerStateBuilder { } #[must_use] - pub fn event(mut self, event: ShipEvent) -> ShipServerStateBuilder { + pub fn event(mut self, event: Holiday) -> ShipServerStateBuilder { self.event = Some(event); self } #[must_use] - pub fn map_builder(mut self, map_builder: Box) -> Maps + Send + Sync>) -> ShipServerStateBuilder { + pub fn map_builder(mut self, map_builder: Box Maps + Send + Sync>) -> ShipServerStateBuilder { self.map_builder = Some(map_builder); self } @@ -481,7 +416,7 @@ impl ShipServerStateBuilder { port: self.port.unwrap_or(SHIP_PORT), shops: ItemShops::default(), blocks: Blocks(blocks), - event: self.event.unwrap_or(ShipEvent::None), + event: self.event.unwrap_or(Holiday::None), map_builder: Arc::new(self.map_builder.unwrap_or(Box::new(generate_free_roam_maps))), drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or(Box::new(DropTable::new))), @@ -522,7 +457,7 @@ pub struct ShipServerState { pub(crate) item_state: items::state::ItemState, shops: ItemShops, pub blocks: Blocks, - event: ShipEvent, + event: Holiday, ip: Ipv4Addr, port: u16, @@ -531,7 +466,7 @@ pub struct ShipServerState { ship_list: Arc>>, shipgate_sender: Option>, trades: TradeState, - map_builder: Arc) -> Maps + Send + Sync>>, + map_builder: Arc Maps + Send + Sync>>, drop_table_builder: Arc DropTable + Send + Sync>>, } diff --git a/tests/common.rs b/tests/common.rs index 6c8b577..1c11777 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -1,10 +1,10 @@ #![allow(dead_code)] -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::EntityGateway; use entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity}; use entity::character::{CharacterEntity, NewCharacterEntity}; -use entity::item::{Meseta, BankName, BankIdentifier}; +use entity::item::{Meseta, BankIdentifier}; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; use maps::room::Difficulty; diff --git a/tests/test_bank.rs b/tests/test_bank.rs index 227e043..c7d7f20 100644 --- a/tests/test_bank.rs +++ b/tests/test_bank.rs @@ -1,5 +1,5 @@ use std::collections::BTreeSet; -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; diff --git a/tests/test_character.rs b/tests/test_character.rs index 9ea3c93..9052c74 100644 --- a/tests/test_character.rs +++ b/tests/test_character.rs @@ -1,4 +1,4 @@ -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; diff --git a/tests/test_exp_gain.rs b/tests/test_exp_gain.rs index 6cecb60..13a0eca 100644 --- a/tests/test_exp_gain.rs +++ b/tests/test_exp_gain.rs @@ -1,8 +1,7 @@ -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::common::leveltable::CharacterLevelTable; +use stats::leveltable::CharacterLevelTable; use elseware::ship::ship::{ShipServerState, SendShipPacket, RecvShipPacket}; -use elseware::ship::location::RoomId; use maps::variant::{MapVariant, MapVariantMode}; use maps::maps::Maps; use maps::area::MapArea; diff --git a/tests/test_item_actions.rs b/tests/test_item_actions.rs index d840cab..9964bd6 100644 --- a/tests/test_item_actions.rs +++ b/tests/test_item_actions.rs @@ -1,4 +1,4 @@ -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; use entity::item; diff --git a/tests/test_item_drop.rs b/tests/test_item_drop.rs index 3f2f55a..20b6a98 100644 --- a/tests/test_item_drop.rs +++ b/tests/test_item_drop.rs @@ -1,13 +1,9 @@ -use elseware::common::serverstate::{ClientId, ServerState}; -use entity::gateway::{EntityGateway, InMemoryGateway}; -use entity::character::SectionID; -use elseware::common::leveltable::CharacterLevelTable; +use networking::serverstate::{ClientId, ServerState}; +use entity::gateway::InMemoryGateway; use elseware::ship::ship::{ShipServerState, SendShipPacket, RecvShipPacket}; -use maps::room::{Episode, Difficulty}; use maps::monster::MonsterType; -use elseware::ship::location::RoomId; -use elseware::ship::drops::{DropTable, MonsterDropStats, MonsterDropType}; -use elseware::ship::drops::rare_drop_table::{RareDropTable, RareDropRate, RareDropItem}; +use drops::{DropTable, MonsterDropStats, MonsterDropType}; +use drops::rare_drop_table::{RareDropTable, RareDropRate, RareDropItem}; use maps::maps::Maps; use maps::area::MapArea; use maps::variant::{MapVariant, MapVariantMode}; diff --git a/tests/test_item_id.rs b/tests/test_item_id.rs index 0d8d70e..06ec3b4 100644 --- a/tests/test_item_id.rs +++ b/tests/test_item_id.rs @@ -1,9 +1,7 @@ -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; -use entity::character::TechLevel; -//use elseware::ship::items::{ClientItemId, ActiveItemEntityId, HeldItemType, FloorItemType}; use libpso::packet::ship::*; use libpso::packet::messages::*; diff --git a/tests/test_item_pickup.rs b/tests/test_item_pickup.rs index ca1b118..fd38cb1 100644 --- a/tests/test_item_pickup.rs +++ b/tests/test_item_pickup.rs @@ -1,4 +1,4 @@ -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; diff --git a/tests/test_item_use.rs b/tests/test_item_use.rs index fab748b..67a29b2 100644 --- a/tests/test_item_use.rs +++ b/tests/test_item_use.rs @@ -1,9 +1,8 @@ -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; use entity::character::TechLevel; -//use elseware::ship::items::{ClientItemId, ActiveItemEntityId, HeldItemType, FloorItemType}; use libpso::packet::ship::*; use libpso::packet::messages::*; diff --git a/tests/test_mags.rs b/tests/test_mags.rs index fe098d9..68adbcd 100644 --- a/tests/test_mags.rs +++ b/tests/test_mags.rs @@ -1,4 +1,4 @@ -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; diff --git a/tests/test_rooms.rs b/tests/test_rooms.rs index 73c2a77..cb10dfb 100644 --- a/tests/test_rooms.rs +++ b/tests/test_rooms.rs @@ -1,8 +1,6 @@ -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; -use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; -use elseware::ship::location::RoomId; use libpso::packet::ship::*; //use libpso::packet::messages::*; diff --git a/tests/test_shops.rs b/tests/test_shops.rs index 6a94a04..c54d907 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -1,9 +1,9 @@ -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket, ShipError}; +use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; use maps::room::Difficulty; -use elseware::ship::items::state::ItemStateError; +use items::state::ItemStateError; use libpso::packet::ship::*; use libpso::packet::messages::*; diff --git a/tests/test_trade.rs b/tests/test_trade.rs index a895ed4..9799156 100644 --- a/tests/test_trade.rs +++ b/tests/test_trade.rs @@ -1,5 +1,5 @@ use std::convert::TryInto; -use elseware::common::serverstate::{ClientId, ServerState}; +use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket, ShipError}; diff --git a/trade/Cargo.toml b/trade/Cargo.toml new file mode 100644 index 0000000..9d588b4 --- /dev/null +++ b/trade/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "trade" +version = "0.1.0" +edition = "2021" + + +[dependencies] +networking = { workspace = true } +items = { workspace = true } + +async-std = { workspace = true } +futures = { workspace = true } +anyhow = { workspace = true } +thiserror = { workspace = true } \ No newline at end of file diff --git a/trade/src/lib.rs b/trade/src/lib.rs new file mode 100644 index 0000000..2629bda --- /dev/null +++ b/trade/src/lib.rs @@ -0,0 +1,4 @@ +pub mod trade; + + +pub use trade::*; diff --git a/src/ship/trade.rs b/trade/src/trade.rs similarity index 79% rename from src/ship/trade.rs rename to trade/src/trade.rs index abe1cd2..a6a7b18 100644 --- a/src/ship/trade.rs +++ b/trade/src/trade.rs @@ -1,45 +1,9 @@ use std::collections::HashMap; -use crate::common::serverstate::ClientId; -use crate::ship::items; +use networking::serverstate::ClientId; +use items; use async_std::sync::{Arc, Mutex, MutexGuard}; use futures::future::{Future, OptionFuture}; - -#[derive(Debug, Clone)] -pub enum TradeItem { - Individual(items::ClientItemId), - Stacked(items::ClientItemId, usize), -} - -impl TradeItem { - pub fn stacked(&self) -> Option<(items::ClientItemId, usize)> { - match self { - TradeItem::Stacked(item_id, amount) => Some((*item_id, *amount)), - _ => None - } - } - - pub fn stacked_mut(&mut self) -> Option<(items::ClientItemId, &mut usize)> { - match self { - TradeItem::Stacked(item_id, ref mut amount) => Some((*item_id, amount)), - _ => None - } - } - - pub fn item_id(&self) -> items::ClientItemId { - match self { - TradeItem::Individual(item_id) => *item_id, - TradeItem::Stacked(item_id, _) => *item_id, - } - } - - pub fn amount(&self) -> usize { - match self { - TradeItem::Individual(_) => 1, - TradeItem::Stacked(_, amount) => *amount, - } - } -} - +use items::trade::TradeItem; #[derive(Debug, Clone, Eq, PartialEq)] pub enum TradeStatus { -- 2.36.0 From cf2bac4ccbfb8d535e18bcab71e3ccf2339a7f82 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 14:41:00 -0700 Subject: [PATCH 31/58] clippy cleanup --- client/src/client.rs | 6 +++--- items/src/actions.rs | 6 +----- items/src/tasks.rs | 2 ++ room/Cargo.toml | 2 +- room/src/room.rs | 8 ++++---- src/bin/main.rs | 2 +- src/ship/mod.rs | 12 ------------ 7 files changed, 12 insertions(+), 26 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index 21b2281..e75ceaa 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -52,7 +52,7 @@ impl Clients { .await; let client = clients .get(&client_id) - .ok_or_else(|| ClientError::NotFound(client_id))? + .ok_or(ClientError::NotFound(client_id))? .read() .await; @@ -75,7 +75,7 @@ impl Clients { for (cindex, client_id) in client_ids.iter().enumerate() { let c = clients .get(client_id) - .ok_or_else(|| ClientError::NotFound(*client_id))? + .ok_or(ClientError::NotFound(*client_id))? .read() .await; client_states[cindex].write(c); @@ -101,7 +101,7 @@ impl Clients { .await; let mut client = clients .get(&client_id) - .ok_or_else(|| ClientError::NotFound(client_id))? + .ok_or(ClientError::NotFound(client_id))? .write() .await; diff --git a/items/src/actions.rs b/items/src/actions.rs index 873e735..0b55d6d 100644 --- a/items/src/actions.rs +++ b/items/src/actions.rs @@ -8,7 +8,6 @@ use std::pin::Pin; use std::iter::IntoIterator; use anyhow::Context; -use libpso::packet::{ship::Message, messages::GameMessage}; use entity::character::{CharacterEntity, CharacterEntityId}; use entity::gateway::{EntityGateway, EntityGatewayTransaction}; use entity::item::{ItemDetail, NewItemEntity, TradeId, ItemModifier}; @@ -22,7 +21,6 @@ use crate::floor::{FloorItem, FloorItemDetail}; use crate::apply_item::{apply_item, ApplyItemAction}; use shops::ShopItem; use drops::{ItemDrop, ItemDropType}; -//use crate::ship::packet::builder; use location::AreaClient; use maps::monster::MonsterType; @@ -1166,8 +1164,7 @@ where let (inventory_item_detail, create_item) = if item_detail.is_stackable() { let tool = item_detail.as_tool().ok_or_else(|| ItemStateError::NotATool(ClientItemId(0xFFFFFFFF)))?; - //let create_item = builder::message::create_stacked_item(area_client, item_id, &tool, 1).map_err(|_err| ItemStateError::Dummy)?; - let create_item = CreateItem::Stacked(area_client, item_id, tool.clone(), 1); + let create_item = CreateItem::Stacked(area_client, item_id, tool, 1); let item_detail = StackedItemDetail { entity_ids: vec![new_item.id], tool @@ -1179,7 +1176,6 @@ where entity_id: new_item.id, item: item_detail, }; - //let create_item = builder::message::create_individual_item(area_client, item_id, &item_detail).map_err(|_err| ItemStateError::Dummy)?; let create_item = CreateItem::Individual(area_client, item_id, item_detail.clone()); (InventoryItemDetail::Individual(item_detail), create_item) }; diff --git a/items/src/tasks.rs b/items/src/tasks.rs index 8a7a307..cf313fc 100644 --- a/items/src/tasks.rs +++ b/items/src/tasks.rs @@ -371,6 +371,8 @@ where Ok((transaction, result)) }) } + +#[allow(clippy::type_complexity)] pub fn trade_items<'a, EG> ( item_state: &'a mut ItemState, entity_gateway: &'a mut EG, diff --git a/room/Cargo.toml b/room/Cargo.toml index 361b597..d081284 100644 --- a/room/Cargo.toml +++ b/room/Cargo.toml @@ -10,7 +10,7 @@ quests = { workspace = true } location = { workspace = true } drops = { workspace = true } -rand= { workspace = true } +rand = { workspace = true } async-std = { workspace = true } futures = { workspace = true } anyhow = { workspace = true } diff --git a/room/src/room.rs b/room/src/room.rs index a065d55..5110d22 100644 --- a/room/src/room.rs +++ b/room/src/room.rs @@ -40,7 +40,7 @@ impl Rooms { pub async fn add(&self, room_id: RoomId, room: RoomState) -> Result<(), anyhow::Error> { *self.0 .get(room_id.0) - .ok_or_else(|| RoomError::Invalid(room_id.0 as u32))? + .ok_or(RoomError::Invalid(room_id.0 as u32))? .write() .await = Some(room); Ok(()) @@ -73,7 +73,7 @@ impl Rooms { { let room = self.0 .get(room_id.0) - .ok_or_else(|| RoomError::Invalid(room_id.0 as u32))? + .ok_or(RoomError::Invalid(room_id.0 as u32))? .read() .await; if let Some(room) = room.as_ref() { @@ -91,7 +91,7 @@ impl Rooms { { let mut room = self.0 .get(room_id.0) - .ok_or_else(|| RoomError::Invalid(room_id.0 as u32))? + .ok_or(RoomError::Invalid(room_id.0 as u32))? .write() .await; @@ -221,7 +221,7 @@ impl RoomState { } } - #[allow(clippy::too_many_arguments)] + #[allow(clippy::too_many_arguments, clippy::type_complexity)] pub fn new (room_id: RoomEntityId, mode: RoomEntityMode, episode: Episode, diff --git a/src/bin/main.rs b/src/bin/main.rs index 34e5793..18fdfbd 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -8,7 +8,7 @@ use elseware::patch::patch::{PatchServerState, generate_patch_tree, load_config, use elseware::ship::ship::ShipServerStateBuilder; use maps::Holiday; -use entity::gateway::{EntityGateway, InMemoryGateway, PostgresGateway}; +use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; use entity::character::NewCharacterEntity; use entity::item::{NewItemEntity, ItemDetail, InventoryItemEntity}; diff --git a/src/ship/mod.rs b/src/ship/mod.rs index f6ada33..cf2a804 100644 --- a/src/ship/mod.rs +++ b/src/ship/mod.rs @@ -1,16 +1,4 @@ #[allow(clippy::module_inception)] pub mod ship; -//pub mod location; -//pub mod character; -//pub mod client; -//pub mod room; -//pub mod items; -//pub mod item_stats; -//pub mod map; -//pub mod monster; -//pub mod drops; pub mod packet; -//pub mod quests; -//pub mod shops; -//pub mod trade; pub mod chatcommand; -- 2.36.0 From 62ad32a9baea8cf007d80eb4da59d563a9b6861f Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 15:18:21 -0700 Subject: [PATCH 32/58] remove another ci cache --- .drone.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.drone.yml b/.drone.yml index a8f5ce2..ac685b1 100644 --- a/.drone.yml +++ b/.drone.yml @@ -9,23 +9,14 @@ concurrency: steps: - name: build image: rustlang/rust:nightly - volumes: - - name: cache - path: /usr/local/cargo commands: - cargo build - name: clippy! image: rustlang/rust:nightly - volumes: - - name: cache - path: /usr/local/cargo commands: - cargo clippy -- --deny warnings - name: test image: rustlang/rust:nightly - volumes: - - name: cache - path: /usr/local/cargo commands: - cargo test --jobs 1 -- 2.36.0 From f0f1b55a381f37adcd640053bdfff402ecd148c6 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 15:20:43 -0700 Subject: [PATCH 33/58] remove some redundant files --- client/src/client.rs | 178 ---------- client/src/lib.rs | 179 ++++++++++- location/src/lib.rs | 677 ++++++++++++++++++++++++++++++++++++++- location/src/location.rs | 676 -------------------------------------- quests/src/lib.rs | 328 ++++++++++++++++++- quests/src/quests.rs | 328 ------------------- room/src/lib.rs | 273 +++++++++++++++- room/src/room.rs | 272 ---------------- trade/src/lib.rs | 132 +++++++- trade/src/trade.rs | 132 -------- 10 files changed, 1579 insertions(+), 1596 deletions(-) delete mode 100644 client/src/client.rs delete mode 100644 location/src/location.rs delete mode 100644 quests/src/quests.rs delete mode 100644 room/src/room.rs delete mode 100644 trade/src/trade.rs diff --git a/client/src/client.rs b/client/src/client.rs deleted file mode 100644 index e75ceaa..0000000 --- a/client/src/client.rs +++ /dev/null @@ -1,178 +0,0 @@ -use std::collections::HashMap; -use async_std::sync::{Arc, RwLock, RwLockReadGuard}; - -use futures::future::BoxFuture; - -use libpso::packet::ship::*; -use libpso::packet::login::Session; - -use networking::serverstate::ClientId; -use entity::account::{UserAccountEntity, UserSettingsEntity}; -use entity::character::CharacterEntity; -use entity::item; - -use items; -use maps::area::MapArea; -use shops::{WeaponShopItem, ToolShopItem, ArmorShopItem}; - - -#[derive(thiserror::Error, Debug)] -pub enum ClientError { - #[error("not found {0}")] - NotFound(ClientId), -} - - -#[derive(Clone, Default)] -pub struct Clients(Arc>>>); - -impl Clients { - pub async fn add(&mut self, client_id: ClientId, client_state: ClientState) { - self.0 - .write() - .await - .insert(client_id, RwLock::new(client_state)); - } - - pub async fn remove(&mut self, client_id: &ClientId) -> Option { - Some(self.0 - .write() - .await - .remove(client_id)? - .into_inner()) - } - - pub async fn with<'a, T, F>(&'a self, client_id: ClientId, func: F) -> Result - where - T: Send, - F: for<'b> FnOnce(&'b ClientState) -> BoxFuture<'b, T> + Send + 'a, - { - let clients = self.0 - .read() - .await; - let client = clients - .get(&client_id) - .ok_or(ClientError::NotFound(client_id))? - .read() - .await; - - Ok(func(&client).await) - } - - pub async fn with_many<'a, T, F, const N: usize>(&'a self, client_ids: [ClientId; N], func: F) -> Result - where - T: Send, - F: for<'b> FnOnce([RwLockReadGuard<'b, ClientState>; N]) -> BoxFuture<'b, T> + Send + 'a, - { - let clients = self.0 - .read() - .await; - - let mut client_states: [std::mem::MaybeUninit>; N] = unsafe { - std::mem::MaybeUninit::uninit().assume_init() - }; - - for (cindex, client_id) in client_ids.iter().enumerate() { - let c = clients - .get(client_id) - .ok_or(ClientError::NotFound(*client_id))? - .read() - .await; - client_states[cindex].write(c); - } - - let client_states = unsafe { - // TODO: this should just be a normal transmute but due to compiler limitations it - // does not yet work with const generics - // https://github.com/rust-lang/rust/issues/61956 - std::mem::transmute_copy::<_, [RwLockReadGuard; N]>(&client_states) - }; - - Ok(func(client_states).await) - } - - pub async fn with_mut<'a, T, F>(&'a self, client_id: ClientId, func: F) -> Result - where - T: Send, - F: for<'b> FnOnce(&'b mut ClientState) -> BoxFuture<'b, T> + Send + 'a, - { - let clients = self.0 - .read() - .await; - let mut client = clients - .get(&client_id) - .ok_or(ClientError::NotFound(client_id))? - .write() - .await; - - Ok(func(&mut client).await) - } -} - - -#[derive(Debug, Clone, Copy)] -pub struct ItemDropLocation { - pub map_area: MapArea, - pub x: f32, - pub z: f32, - pub item_id: items::ClientItemId, -} - -pub struct LoadingQuest { - pub header_bin: Option, - pub header_dat: Option, -} - - -pub struct ClientState { - pub user: UserAccountEntity, - pub settings: UserSettingsEntity, - pub character: CharacterEntity, - _session: Session, - //guildcard: GuildCard, - pub block: usize, - pub item_drop_location: Option, - pub done_loading_quest: bool, - pub area: Option, - pub x: f32, - pub y: f32, - pub z: f32, - pub weapon_shop: Vec, - pub tool_shop: Vec, - pub armor_shop: Vec, - pub tek: Option<(items::ClientItemId, item::weapon::TekSpecialModifier, item::weapon::TekPercentModifier, i32)>, - pub character_playtime: chrono::Duration, - pub log_on_time: chrono::DateTime, -} - -impl ClientState { - pub fn new(user: UserAccountEntity, settings: UserSettingsEntity, character: CharacterEntity, session: Session) -> ClientState { - let character_playtime = chrono::Duration::seconds(character.playtime as i64); - ClientState { - user, - settings, - character, - _session: session, - block: 0, - item_drop_location: None, - done_loading_quest: false, - area: None, - x: 0.0, - y: 0.0, - z: 0.0, - weapon_shop: Vec::new(), - tool_shop: Vec::new(), - armor_shop: Vec::new(), - tek: None, - character_playtime, - log_on_time: chrono::Utc::now(), - } - } - - pub fn update_playtime(&mut self) { - let additional_playtime = chrono::Utc::now() - self.log_on_time; - self.character.playtime = (self.character_playtime + additional_playtime).num_seconds() as u32; - } -} - - diff --git a/client/src/lib.rs b/client/src/lib.rs index c8ab57b..e75ceaa 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1,3 +1,178 @@ -pub mod client; +use std::collections::HashMap; +use async_std::sync::{Arc, RwLock, RwLockReadGuard}; + +use futures::future::BoxFuture; + +use libpso::packet::ship::*; +use libpso::packet::login::Session; + +use networking::serverstate::ClientId; +use entity::account::{UserAccountEntity, UserSettingsEntity}; +use entity::character::CharacterEntity; +use entity::item; + +use items; +use maps::area::MapArea; +use shops::{WeaponShopItem, ToolShopItem, ArmorShopItem}; + + +#[derive(thiserror::Error, Debug)] +pub enum ClientError { + #[error("not found {0}")] + NotFound(ClientId), +} + + +#[derive(Clone, Default)] +pub struct Clients(Arc>>>); + +impl Clients { + pub async fn add(&mut self, client_id: ClientId, client_state: ClientState) { + self.0 + .write() + .await + .insert(client_id, RwLock::new(client_state)); + } + + pub async fn remove(&mut self, client_id: &ClientId) -> Option { + Some(self.0 + .write() + .await + .remove(client_id)? + .into_inner()) + } + + pub async fn with<'a, T, F>(&'a self, client_id: ClientId, func: F) -> Result + where + T: Send, + F: for<'b> FnOnce(&'b ClientState) -> BoxFuture<'b, T> + Send + 'a, + { + let clients = self.0 + .read() + .await; + let client = clients + .get(&client_id) + .ok_or(ClientError::NotFound(client_id))? + .read() + .await; + + Ok(func(&client).await) + } + + pub async fn with_many<'a, T, F, const N: usize>(&'a self, client_ids: [ClientId; N], func: F) -> Result + where + T: Send, + F: for<'b> FnOnce([RwLockReadGuard<'b, ClientState>; N]) -> BoxFuture<'b, T> + Send + 'a, + { + let clients = self.0 + .read() + .await; + + let mut client_states: [std::mem::MaybeUninit>; N] = unsafe { + std::mem::MaybeUninit::uninit().assume_init() + }; + + for (cindex, client_id) in client_ids.iter().enumerate() { + let c = clients + .get(client_id) + .ok_or(ClientError::NotFound(*client_id))? + .read() + .await; + client_states[cindex].write(c); + } + + let client_states = unsafe { + // TODO: this should just be a normal transmute but due to compiler limitations it + // does not yet work with const generics + // https://github.com/rust-lang/rust/issues/61956 + std::mem::transmute_copy::<_, [RwLockReadGuard; N]>(&client_states) + }; + + Ok(func(client_states).await) + } + + pub async fn with_mut<'a, T, F>(&'a self, client_id: ClientId, func: F) -> Result + where + T: Send, + F: for<'b> FnOnce(&'b mut ClientState) -> BoxFuture<'b, T> + Send + 'a, + { + let clients = self.0 + .read() + .await; + let mut client = clients + .get(&client_id) + .ok_or(ClientError::NotFound(client_id))? + .write() + .await; + + Ok(func(&mut client).await) + } +} + + +#[derive(Debug, Clone, Copy)] +pub struct ItemDropLocation { + pub map_area: MapArea, + pub x: f32, + pub z: f32, + pub item_id: items::ClientItemId, +} + +pub struct LoadingQuest { + pub header_bin: Option, + pub header_dat: Option, +} + + +pub struct ClientState { + pub user: UserAccountEntity, + pub settings: UserSettingsEntity, + pub character: CharacterEntity, + _session: Session, + //guildcard: GuildCard, + pub block: usize, + pub item_drop_location: Option, + pub done_loading_quest: bool, + pub area: Option, + pub x: f32, + pub y: f32, + pub z: f32, + pub weapon_shop: Vec, + pub tool_shop: Vec, + pub armor_shop: Vec, + pub tek: Option<(items::ClientItemId, item::weapon::TekSpecialModifier, item::weapon::TekPercentModifier, i32)>, + pub character_playtime: chrono::Duration, + pub log_on_time: chrono::DateTime, +} + +impl ClientState { + pub fn new(user: UserAccountEntity, settings: UserSettingsEntity, character: CharacterEntity, session: Session) -> ClientState { + let character_playtime = chrono::Duration::seconds(character.playtime as i64); + ClientState { + user, + settings, + character, + _session: session, + block: 0, + item_drop_location: None, + done_loading_quest: false, + area: None, + x: 0.0, + y: 0.0, + z: 0.0, + weapon_shop: Vec::new(), + tool_shop: Vec::new(), + armor_shop: Vec::new(), + tek: None, + character_playtime, + log_on_time: chrono::Utc::now(), + } + } + + pub fn update_playtime(&mut self) { + let additional_playtime = chrono::Utc::now() - self.log_on_time; + self.character.playtime = (self.character_playtime + additional_playtime).num_seconds() as u32; + } +} + -pub use client::*; diff --git a/location/src/lib.rs b/location/src/lib.rs index dd9bd1e..3dd0b2b 100644 --- a/location/src/lib.rs +++ b/location/src/lib.rs @@ -1,3 +1,676 @@ -pub mod location; +#![allow(dead_code, unused_must_use)] +use std::collections::HashMap; +use std::time::SystemTime; +use thiserror::Error; +use networking::serverstate::ClientId; -pub use location::*; +use async_std::sync::{Arc, RwLock}; +use futures::{stream, StreamExt}; +use std::pin::pin; + +pub const MAX_ROOMS: usize = 128; + +pub enum AreaType { + Room, + Lobby, +} + + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct LobbyId(pub usize); + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, derive_more::Display)] +pub struct RoomId(pub usize); + +impl LobbyId { + pub fn id(&self) -> u8 { + self.0 as u8 + } +} + + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum CreateRoomError { + #[error("no open slots")] + NoOpenSlots, + #[error("client already in area")] + ClientInAreaAlready, + #[error("join error")] + JoinError, +} + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum JoinRoomError { + #[error("room does not exist")] + RoomDoesNotExist, + #[error("room is full")] + RoomFull, + #[error("client already in area")] + ClientInAreaAlready, +} + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum JoinLobbyError { + #[error("lobby does not exist")] + LobbyDoesNotExist, + #[error("lobby is full")] + LobbyFull, + #[error("client already in area")] + ClientInAreaAlready, +} + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum GetAreaError { + #[error("not in a room")] + NotInRoom, + #[error("not in a lobby")] + NotInLobby, + #[error("get area: invalid client")] + InvalidClient, +} + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum ClientRemovalError { + #[error("client removal: client not in area")] + ClientNotInArea, + #[error("client removal: invalid area")] + InvalidArea, +} + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum GetClientsError { + #[error("invalid client")] + InvalidClient, + #[error("invalid area")] + InvalidArea, +} + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum GetNeighborError { + #[error("get neighbor: invalid client")] + InvalidClient, + #[error("get neighbor: invalid area")] + InvalidArea, +} + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum GetLeaderError { + #[error("get leader: invalid client")] + InvalidClient, + #[error("get leader: invalid area")] + InvalidArea, + #[error("get leader: client not in area")] + NoClientInArea, +} + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum ClientLocationError { + #[error("create room error {0}")] + CreateRoomError(#[from] CreateRoomError), + #[error("join room error {0}")] + JoinRoomError(#[from] JoinRoomError), + #[error("join lobby error {0}")] + JoinLobbyError(#[from] JoinLobbyError), + #[error("get area error {0}")] + GetAreaError(#[from] GetAreaError), + #[error("client removal error {0}")] + ClientRemovalError(#[from] ClientRemovalError), + #[error("get clients error {0}")] + GetClientsError(#[from] GetClientsError), + #[error("get neighbor error {0}")] + GetNeighborError(#[from] GetNeighborError), + #[error("get leader error {0}")] + GetLeaderError(#[from] GetLeaderError) +} + + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct LocalClientId(usize); + +impl LocalClientId { + pub fn id(&self) -> u8 { + self.0 as u8 + } +} + +impl PartialEq for LocalClientId { + fn eq(&self, other: &u8) -> bool { + self.0 == *other as usize + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct AreaClient { + pub client: ClientId, + pub local_client: LocalClientId, + time_join: SystemTime, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +struct Lobby([Option; 12]); +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +struct Room([Option; 4]); + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum RoomLobby { + Room(RoomId), + Lobby(LobbyId), +} + +#[derive(Clone, Debug)] +pub struct ClientLocation { + lobbies: [Arc>; 15], + rooms: [Arc>>; MAX_ROOMS], + client_location: Arc>>, +} + +impl Default for ClientLocation { + fn default() -> ClientLocation { + ClientLocation { + lobbies: core::array::from_fn(|_| Arc::new(RwLock::new(Lobby([None; 12])))), + rooms: core::array::from_fn(|_| Arc::new(RwLock::new(None))), + client_location: Arc::new(RwLock::new(HashMap::new())), + } + } +} + + +impl ClientLocation { + pub async fn add_client_to_lobby(&self, id: ClientId, lobby_id: LobbyId) -> Result<(), JoinLobbyError> { + { + let lobby = self.lobbies + .get(lobby_id.0) + .ok_or(JoinLobbyError::LobbyDoesNotExist)? + .read() + .await; + if lobby.0.iter().all(|c| c.is_some()) { + return Err(JoinLobbyError::LobbyFull); + } + } + self.remove_client_from_area(id).await; + + let mut lobby = self.lobbies + .get(lobby_id.0) + .ok_or(JoinLobbyError::LobbyDoesNotExist)? + .write() + .await; + let (index, empty_slot) = lobby.0.iter_mut() + .enumerate() + .find(|(_, k)| k.is_none()) + .ok_or(JoinLobbyError::LobbyFull)?; + *empty_slot = Some(AreaClient { + client: id, + local_client: LocalClientId(index), + time_join: SystemTime::now(), + }); + self.client_location + .write() + .await + .insert(id, RoomLobby::Lobby(lobby_id)); + Ok(()) + } + + pub async fn add_client_to_next_available_lobby(&self, id: ClientId, lobby: LobbyId) -> Result { + pin!(stream::iter(0..15) + .filter_map(|lobby_index| async move { + let new_lobby = LobbyId((lobby.0 + lobby_index) % 15); + Some((new_lobby, self.add_client_to_lobby(id, new_lobby).await.ok()?)) + })) + .next() + .await + .map(|l| l.0) + .ok_or(JoinLobbyError::LobbyFull) + } + + pub async fn create_new_room(&mut self, id: ClientId) -> Result { + let (index, empty_slot) = Box::pin(stream::iter(self.rooms.iter()) + .enumerate() + .filter(|(_, r)| async {r.read().await.is_none()})) + .next() + .await + .ok_or(CreateRoomError::NoOpenSlots)?; + *empty_slot.write().await = Some(Room([None; 4])); + self.add_client_to_room(id, RoomId(index)) + .await + .map_err(|_err| CreateRoomError::JoinError)?; + Ok(RoomId(index)) + } + + pub async fn add_client_to_room(&mut self, id: ClientId, room: RoomId) -> Result<(), JoinRoomError> { + let mut r = self.rooms.get(room.0) + .ok_or(JoinRoomError::RoomDoesNotExist)? + .as_ref() + .write() + .await; + let r = r.as_mut() + .ok_or(JoinRoomError::RoomDoesNotExist)?; + let (index, empty_slot) = r.0.iter_mut() + .enumerate() + .find(|(_, k)| k.is_none()) + .ok_or(JoinRoomError::RoomFull)?; + *empty_slot = Some(AreaClient { + client: id, + local_client: LocalClientId(index), + time_join: SystemTime::now(), + }); + self.remove_client_from_area(id).await; + self.client_location + .write() + .await + .insert(id, RoomLobby::Room(room)); + Ok(()) + } + + pub async fn get_all_clients_by_client(&self, id: ClientId) -> Result, GetNeighborError> { + let area = self.client_location + .read() + .await; + let area = area + .get(&id) + .ok_or(GetNeighborError::InvalidClient)?; + match area { + RoomLobby::Room(room) => { + Ok(self.get_clients_in_room(*room).await.map_err(|_| GetNeighborError::InvalidArea)? + .into_iter() + .collect()) + }, + RoomLobby::Lobby(lobby) => { + Ok(self.get_clients_in_lobby(*lobby).await.map_err(|_| GetNeighborError::InvalidArea)? + .into_iter() + .collect()) + } + } + } + + pub async fn get_client_neighbors(&self, id: ClientId) -> Result, GetNeighborError> { + let area = self.client_location + .read() + .await; + let area = area + .get(&id) + .ok_or(GetNeighborError::InvalidClient)?; + match area { + RoomLobby::Room(room) => { + Ok(self.get_clients_in_room(*room).await.map_err(|_| GetNeighborError::InvalidArea)? + .into_iter() + .filter(|c| c.client != id) + .collect()) + }, + RoomLobby::Lobby(lobby) => { + Ok(self.get_clients_in_lobby(*lobby).await.map_err(|_| GetNeighborError::InvalidArea)? + .into_iter() + .filter(|c| c.client != id) + .collect()) + } + } + } + + pub async fn get_room_leader(&self, room: RoomId) -> Result { + let r = self.rooms[room.0] + .as_ref() + .read() + .await + .ok_or(GetLeaderError::InvalidArea)?; + let mut r = r + .0 + .iter() + .flatten() + .collect::>(); + r.sort_by_key(|k| k.time_join); + let c = r.get(0) + .ok_or(GetLeaderError::NoClientInArea)?; + Ok(**c) + } + + pub async fn get_lobby_leader(&self, lobby: LobbyId) -> Result { + let l = self.lobbies[lobby.0] + .read() + .await; + let mut l = l + .0 + .iter() + .flatten() + .collect::>(); + l.sort_by_key(|k| k.time_join); + let c = l.get(0).ok_or(GetLeaderError::NoClientInArea)?; + Ok(**c) + } + + pub async fn get_area_leader(&self, roomlobby: RoomLobby) -> Result { + match roomlobby { + RoomLobby::Room(room) => { + self.get_room_leader(room).await + }, + RoomLobby::Lobby(lobby) => { + self.get_lobby_leader(lobby).await + } + } + } + + pub async fn get_leader_by_client(&self, id: ClientId) -> Result { + let area = self.client_location + .read() + .await; + let area = area + .get(&id) + .ok_or(GetLeaderError::InvalidClient)?; + match area { + RoomLobby::Room(room) => { + self.get_room_leader(*room).await + }, + RoomLobby::Lobby(lobby) => { + self.get_lobby_leader(*lobby).await + } + } + } + + pub async fn get_clients_in_lobby(&self, lobby: LobbyId) -> Result, GetClientsError> { + Ok(self.lobbies + .get(lobby.0) + .ok_or(GetClientsError::InvalidArea)? + .read() + .await + .0 + .iter() + .filter_map(|client| { + client.map(|c| { + c + }) + }).collect()) + } + + pub async fn get_clients_in_room(&self, room: RoomId) -> Result, GetClientsError> { + Ok(self.rooms.get(room.0) + .ok_or(GetClientsError::InvalidArea)? + .as_ref() + .read() + .await + .ok_or(GetClientsError::InvalidArea)? + .0 + .iter() + .filter_map(|client| { + client.map(|c| { + c + }) + }).collect()) + } + + pub async fn get_local_client(&self, id: ClientId) -> Result { + let area = self.client_location + .read() + .await; + let area = area + .get(&id) + .ok_or(GetClientsError::InvalidClient)?; + match area { + RoomLobby::Room(room) => { + self.get_clients_in_room(*room) + .await + .map_err(|_| GetClientsError::InvalidArea)? + .into_iter() + .find(|c| c.client == id) + .ok_or(GetClientsError::InvalidClient) + }, + RoomLobby::Lobby(lobby) => { + self.get_clients_in_lobby(*lobby) + .await + .map_err(|_| GetClientsError::InvalidArea)? + .into_iter() + .find(|c| c.client == id) + .ok_or(GetClientsError::InvalidClient) + } + } + } + + pub async fn get_area(&self, id: ClientId) -> Result { + self.client_location + .read() + .await + .get(&id) + .ok_or(GetAreaError::InvalidClient) + .map(Clone::clone) + } + + pub async fn get_room(&self, id: ClientId) -> Result { + if let RoomLobby::Room(room) = self.client_location.read().await.get(&id).ok_or(GetAreaError::InvalidClient)? { + Ok(*room) + } + else { + Err(GetAreaError::NotInRoom) + } + } + + pub async fn get_lobby(&self, id: ClientId) -> Result { + if let RoomLobby::Lobby(lobby) = self.client_location.read().await.get(&id).ok_or(GetAreaError::InvalidClient)? { + Ok(*lobby) + } + else { + Err(GetAreaError::NotInLobby) + } + } + + pub async fn remove_client_from_area(&self, id: ClientId) -> Result<(), ClientRemovalError> { + fn remove_client(id: ClientId, client_list : &mut [Option; N]) { + client_list + .iter_mut() + .filter(|client| { + client.map_or(false, |c| { + c.client == id + }) + }) + .for_each(|client| { + *client = None + }); + } + + let area = self.client_location + .read() + .await; + let area = area + .get(&id) + .ok_or(ClientRemovalError::ClientNotInArea)?; + match area { + RoomLobby::Room(room) => { + let mut r = self.rooms.get(room.0) + .ok_or(ClientRemovalError::InvalidArea)? + .as_ref() + .write() + .await; + if let Some(r) = r.as_mut() { + remove_client(id, &mut r.0) + } + else { + return Err(ClientRemovalError::InvalidArea) + } + }, + RoomLobby::Lobby(lobby) => { + remove_client(id, &mut self.lobbies[lobby.0].write().await.0) + } + }; + + Ok(()) + } +} + + + + + + + + +#[cfg(test)] +mod test { + use super::*; + + #[async_std::test] + async fn test_add_client_to_lobby() { + let cl = ClientLocation::default(); + cl.add_client_to_lobby(ClientId(12), LobbyId(0)).await.unwrap(); + cl.add_client_to_lobby(ClientId(13), LobbyId(1)).await.unwrap(); + cl.add_client_to_lobby(ClientId(14), LobbyId(0)).await.unwrap(); + + assert!(cl.get_clients_in_lobby(LobbyId(0)).await.into_iter().flatten().map(|c| (c.client, c.local_client)).collect::>() == vec![ + (ClientId(12), LocalClientId(0)), + (ClientId(14), LocalClientId(1)), + ]); + } + + #[async_std::test] + async fn test_add_client_to_full_lobby() { + let cl = ClientLocation::default(); + for i in 0..12 { + cl.add_client_to_lobby(ClientId(i), LobbyId(0)).await.unwrap(); + } + assert!(cl.add_client_to_lobby(ClientId(99), LobbyId(0)).await == Err(JoinLobbyError::LobbyFull)); + } + + #[async_std::test] + async fn test_add_client_to_next_available_lobby() { + let cl = ClientLocation::default(); + for lobby in 1..4 { + for i in 0..12 { + cl.add_client_to_lobby(ClientId(lobby*12+i), LobbyId(lobby)).await.unwrap(); + } + } + assert!(cl.add_client_to_next_available_lobby(ClientId(99), LobbyId(1)).await == Ok(LobbyId(4))); + } + + #[async_std::test] + async fn test_add_to_lobby_when_all_are_full() { + let cl = ClientLocation::default(); + for lobby in 0..15 { + for i in 0..12 { + cl.add_client_to_lobby(ClientId(lobby*12+i), LobbyId(lobby)).await.unwrap(); + } + } + assert_eq!(cl.add_client_to_next_available_lobby(ClientId(99), LobbyId(1)).await, Err(JoinLobbyError::LobbyFull)); + } + + #[async_std::test] + async fn test_new_room() { + let mut cl = ClientLocation::default(); + assert!(cl.create_new_room(ClientId(12)).await == Ok(RoomId(0))); + } + + #[async_std::test] + async fn test_add_client_to_room() { + let mut cl = ClientLocation::default(); + let room = cl.create_new_room(ClientId(12)).await.unwrap(); + assert!(cl.add_client_to_room(ClientId(234), room).await == Ok(())); + assert!(cl.get_clients_in_room(room).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>() == vec![ + (ClientId(12), LocalClientId(0)), + (ClientId(234), LocalClientId(1)), + ]); + } + + #[async_std::test] + async fn test_no_new_room_slots() { + let mut cl = ClientLocation::default(); + for i in 0..128 { + cl.create_new_room(ClientId(i)).await; + } + assert!(cl.create_new_room(ClientId(234)).await == Err(CreateRoomError::NoOpenSlots)); + } + + #[async_std::test] + async fn test_joining_full_room() { + let mut cl = ClientLocation::default(); + let room = cl.create_new_room(ClientId(0)).await.unwrap(); + assert!(cl.add_client_to_room(ClientId(1), room).await == Ok(())); + assert!(cl.add_client_to_room(ClientId(2), room).await == Ok(())); + assert!(cl.add_client_to_room(ClientId(3), room).await == Ok(())); + assert!(cl.add_client_to_room(ClientId(234), room).await == Err(JoinRoomError::RoomFull)); + } + + #[async_std::test] + async fn test_adding_client_to_room_removes_from_lobby() { + let mut cl = ClientLocation::default(); + cl.add_client_to_lobby(ClientId(93), LobbyId(0)).await; + cl.add_client_to_lobby(ClientId(23), LobbyId(0)).await; + cl.add_client_to_lobby(ClientId(51), LobbyId(0)).await; + cl.add_client_to_lobby(ClientId(12), LobbyId(0)).await; + + let room = cl.create_new_room(ClientId(51)).await.unwrap(); + assert!(cl.add_client_to_room(ClientId(93), room).await == Ok(())); + assert!(cl.get_clients_in_lobby(LobbyId(0)).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>() == vec![ + (ClientId(23), LocalClientId(1)), + (ClientId(12), LocalClientId(3)), + ]); + assert!(cl.get_clients_in_room(room).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>() == vec![ + (ClientId(51), LocalClientId(0)), + (ClientId(93), LocalClientId(1)), + ]); + } + + #[async_std::test] + async fn test_getting_neighbors() { + let cl = ClientLocation::default(); + cl.add_client_to_lobby(ClientId(93), LobbyId(0)).await.unwrap(); + cl.add_client_to_lobby(ClientId(23), LobbyId(0)).await.unwrap(); + cl.add_client_to_lobby(ClientId(51), LobbyId(0)).await.unwrap(); + cl.add_client_to_lobby(ClientId(12), LobbyId(0)).await.unwrap(); + + assert!(cl.get_client_neighbors(ClientId(23)).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>() == vec![ + (ClientId(93), LocalClientId(0)), + (ClientId(51), LocalClientId(2)), + (ClientId(12), LocalClientId(3)), + ]); + } + + #[async_std::test] + async fn test_failing_to_join_lobby_does_not_remove_from_current_area() { + let cl = ClientLocation::default(); + for i in 0..12 { + cl.add_client_to_lobby(ClientId(i), LobbyId(0)).await.unwrap(); + } + assert!(cl.add_client_to_lobby(ClientId(99), LobbyId(1)).await.is_ok()); + assert!(cl.add_client_to_lobby(ClientId(99), LobbyId(0)).await.is_err()); + assert_eq!(cl.get_clients_in_lobby(LobbyId(0)).await.unwrap().len(), 12); + assert_eq!( + cl.get_clients_in_lobby(LobbyId(1)).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>(), + vec![(ClientId(99), LocalClientId(0))] + ); + } + + #[async_std::test] + async fn test_get_leader() { + let cl = ClientLocation::default(); + cl.add_client_to_lobby(ClientId(93), LobbyId(0)).await; + cl.add_client_to_lobby(ClientId(23), LobbyId(0)).await; + cl.add_client_to_lobby(ClientId(51), LobbyId(0)).await; + cl.add_client_to_lobby(ClientId(12), LobbyId(0)).await; + + assert!(cl.get_leader_by_client(ClientId(51)).await.map(|c| (c.client, c.local_client)) == Ok((ClientId(93), LocalClientId(0)))); + } + + #[async_std::test] + async fn test_remove_client_from_room() { + let mut cl = ClientLocation::default(); + let room = cl.create_new_room(ClientId(51)).await.unwrap(); + cl.add_client_to_room(ClientId(93), room).await; + cl.add_client_to_room(ClientId(23), room).await; + cl.remove_client_from_area(ClientId(51)).await; + cl.add_client_to_room(ClientId(12), room).await; + + assert!(cl.get_clients_in_room(room).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>() == vec![ + (ClientId(12), LocalClientId(0)), + (ClientId(93), LocalClientId(1)), + (ClientId(23), LocalClientId(2)), + ]); + } + + #[async_std::test] + async fn test_leader_changes_on_leader_leaving() { + let mut cl = ClientLocation::default(); + let room = cl.create_new_room(ClientId(51)).await.unwrap(); + cl.add_client_to_room(ClientId(93), room).await.unwrap(); + cl.add_client_to_room(ClientId(23), room).await.unwrap(); + cl.remove_client_from_area(ClientId(51)).await.unwrap(); + cl.add_client_to_room(ClientId(12), room).await.unwrap(); + cl.remove_client_from_area(ClientId(23)).await.unwrap(); + cl.add_client_to_room(ClientId(99), room).await.unwrap(); + + assert!(cl.get_leader_by_client(ClientId(12)).await.map(|c| (c.client, c.local_client)) == Ok((ClientId(93), LocalClientId(1)))); + } +} diff --git a/location/src/location.rs b/location/src/location.rs deleted file mode 100644 index 3dd0b2b..0000000 --- a/location/src/location.rs +++ /dev/null @@ -1,676 +0,0 @@ -#![allow(dead_code, unused_must_use)] -use std::collections::HashMap; -use std::time::SystemTime; -use thiserror::Error; -use networking::serverstate::ClientId; - -use async_std::sync::{Arc, RwLock}; -use futures::{stream, StreamExt}; -use std::pin::pin; - -pub const MAX_ROOMS: usize = 128; - -pub enum AreaType { - Room, - Lobby, -} - - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct LobbyId(pub usize); - -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, derive_more::Display)] -pub struct RoomId(pub usize); - -impl LobbyId { - pub fn id(&self) -> u8 { - self.0 as u8 - } -} - - -#[derive(Error, Debug, PartialEq, Eq)] -pub enum CreateRoomError { - #[error("no open slots")] - NoOpenSlots, - #[error("client already in area")] - ClientInAreaAlready, - #[error("join error")] - JoinError, -} - -#[derive(Error, Debug, PartialEq, Eq)] -pub enum JoinRoomError { - #[error("room does not exist")] - RoomDoesNotExist, - #[error("room is full")] - RoomFull, - #[error("client already in area")] - ClientInAreaAlready, -} - -#[derive(Error, Debug, PartialEq, Eq)] -pub enum JoinLobbyError { - #[error("lobby does not exist")] - LobbyDoesNotExist, - #[error("lobby is full")] - LobbyFull, - #[error("client already in area")] - ClientInAreaAlready, -} - -#[derive(Error, Debug, PartialEq, Eq)] -pub enum GetAreaError { - #[error("not in a room")] - NotInRoom, - #[error("not in a lobby")] - NotInLobby, - #[error("get area: invalid client")] - InvalidClient, -} - -#[derive(Error, Debug, PartialEq, Eq)] -pub enum ClientRemovalError { - #[error("client removal: client not in area")] - ClientNotInArea, - #[error("client removal: invalid area")] - InvalidArea, -} - -#[derive(Error, Debug, PartialEq, Eq)] -pub enum GetClientsError { - #[error("invalid client")] - InvalidClient, - #[error("invalid area")] - InvalidArea, -} - -#[derive(Error, Debug, PartialEq, Eq)] -pub enum GetNeighborError { - #[error("get neighbor: invalid client")] - InvalidClient, - #[error("get neighbor: invalid area")] - InvalidArea, -} - -#[derive(Error, Debug, PartialEq, Eq)] -pub enum GetLeaderError { - #[error("get leader: invalid client")] - InvalidClient, - #[error("get leader: invalid area")] - InvalidArea, - #[error("get leader: client not in area")] - NoClientInArea, -} - -#[derive(Error, Debug, PartialEq, Eq)] -pub enum ClientLocationError { - #[error("create room error {0}")] - CreateRoomError(#[from] CreateRoomError), - #[error("join room error {0}")] - JoinRoomError(#[from] JoinRoomError), - #[error("join lobby error {0}")] - JoinLobbyError(#[from] JoinLobbyError), - #[error("get area error {0}")] - GetAreaError(#[from] GetAreaError), - #[error("client removal error {0}")] - ClientRemovalError(#[from] ClientRemovalError), - #[error("get clients error {0}")] - GetClientsError(#[from] GetClientsError), - #[error("get neighbor error {0}")] - GetNeighborError(#[from] GetNeighborError), - #[error("get leader error {0}")] - GetLeaderError(#[from] GetLeaderError) -} - - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct LocalClientId(usize); - -impl LocalClientId { - pub fn id(&self) -> u8 { - self.0 as u8 - } -} - -impl PartialEq for LocalClientId { - fn eq(&self, other: &u8) -> bool { - self.0 == *other as usize - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct AreaClient { - pub client: ClientId, - pub local_client: LocalClientId, - time_join: SystemTime, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -struct Lobby([Option; 12]); -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -struct Room([Option; 4]); - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum RoomLobby { - Room(RoomId), - Lobby(LobbyId), -} - -#[derive(Clone, Debug)] -pub struct ClientLocation { - lobbies: [Arc>; 15], - rooms: [Arc>>; MAX_ROOMS], - client_location: Arc>>, -} - -impl Default for ClientLocation { - fn default() -> ClientLocation { - ClientLocation { - lobbies: core::array::from_fn(|_| Arc::new(RwLock::new(Lobby([None; 12])))), - rooms: core::array::from_fn(|_| Arc::new(RwLock::new(None))), - client_location: Arc::new(RwLock::new(HashMap::new())), - } - } -} - - -impl ClientLocation { - pub async fn add_client_to_lobby(&self, id: ClientId, lobby_id: LobbyId) -> Result<(), JoinLobbyError> { - { - let lobby = self.lobbies - .get(lobby_id.0) - .ok_or(JoinLobbyError::LobbyDoesNotExist)? - .read() - .await; - if lobby.0.iter().all(|c| c.is_some()) { - return Err(JoinLobbyError::LobbyFull); - } - } - self.remove_client_from_area(id).await; - - let mut lobby = self.lobbies - .get(lobby_id.0) - .ok_or(JoinLobbyError::LobbyDoesNotExist)? - .write() - .await; - let (index, empty_slot) = lobby.0.iter_mut() - .enumerate() - .find(|(_, k)| k.is_none()) - .ok_or(JoinLobbyError::LobbyFull)?; - *empty_slot = Some(AreaClient { - client: id, - local_client: LocalClientId(index), - time_join: SystemTime::now(), - }); - self.client_location - .write() - .await - .insert(id, RoomLobby::Lobby(lobby_id)); - Ok(()) - } - - pub async fn add_client_to_next_available_lobby(&self, id: ClientId, lobby: LobbyId) -> Result { - pin!(stream::iter(0..15) - .filter_map(|lobby_index| async move { - let new_lobby = LobbyId((lobby.0 + lobby_index) % 15); - Some((new_lobby, self.add_client_to_lobby(id, new_lobby).await.ok()?)) - })) - .next() - .await - .map(|l| l.0) - .ok_or(JoinLobbyError::LobbyFull) - } - - pub async fn create_new_room(&mut self, id: ClientId) -> Result { - let (index, empty_slot) = Box::pin(stream::iter(self.rooms.iter()) - .enumerate() - .filter(|(_, r)| async {r.read().await.is_none()})) - .next() - .await - .ok_or(CreateRoomError::NoOpenSlots)?; - *empty_slot.write().await = Some(Room([None; 4])); - self.add_client_to_room(id, RoomId(index)) - .await - .map_err(|_err| CreateRoomError::JoinError)?; - Ok(RoomId(index)) - } - - pub async fn add_client_to_room(&mut self, id: ClientId, room: RoomId) -> Result<(), JoinRoomError> { - let mut r = self.rooms.get(room.0) - .ok_or(JoinRoomError::RoomDoesNotExist)? - .as_ref() - .write() - .await; - let r = r.as_mut() - .ok_or(JoinRoomError::RoomDoesNotExist)?; - let (index, empty_slot) = r.0.iter_mut() - .enumerate() - .find(|(_, k)| k.is_none()) - .ok_or(JoinRoomError::RoomFull)?; - *empty_slot = Some(AreaClient { - client: id, - local_client: LocalClientId(index), - time_join: SystemTime::now(), - }); - self.remove_client_from_area(id).await; - self.client_location - .write() - .await - .insert(id, RoomLobby::Room(room)); - Ok(()) - } - - pub async fn get_all_clients_by_client(&self, id: ClientId) -> Result, GetNeighborError> { - let area = self.client_location - .read() - .await; - let area = area - .get(&id) - .ok_or(GetNeighborError::InvalidClient)?; - match area { - RoomLobby::Room(room) => { - Ok(self.get_clients_in_room(*room).await.map_err(|_| GetNeighborError::InvalidArea)? - .into_iter() - .collect()) - }, - RoomLobby::Lobby(lobby) => { - Ok(self.get_clients_in_lobby(*lobby).await.map_err(|_| GetNeighborError::InvalidArea)? - .into_iter() - .collect()) - } - } - } - - pub async fn get_client_neighbors(&self, id: ClientId) -> Result, GetNeighborError> { - let area = self.client_location - .read() - .await; - let area = area - .get(&id) - .ok_or(GetNeighborError::InvalidClient)?; - match area { - RoomLobby::Room(room) => { - Ok(self.get_clients_in_room(*room).await.map_err(|_| GetNeighborError::InvalidArea)? - .into_iter() - .filter(|c| c.client != id) - .collect()) - }, - RoomLobby::Lobby(lobby) => { - Ok(self.get_clients_in_lobby(*lobby).await.map_err(|_| GetNeighborError::InvalidArea)? - .into_iter() - .filter(|c| c.client != id) - .collect()) - } - } - } - - pub async fn get_room_leader(&self, room: RoomId) -> Result { - let r = self.rooms[room.0] - .as_ref() - .read() - .await - .ok_or(GetLeaderError::InvalidArea)?; - let mut r = r - .0 - .iter() - .flatten() - .collect::>(); - r.sort_by_key(|k| k.time_join); - let c = r.get(0) - .ok_or(GetLeaderError::NoClientInArea)?; - Ok(**c) - } - - pub async fn get_lobby_leader(&self, lobby: LobbyId) -> Result { - let l = self.lobbies[lobby.0] - .read() - .await; - let mut l = l - .0 - .iter() - .flatten() - .collect::>(); - l.sort_by_key(|k| k.time_join); - let c = l.get(0).ok_or(GetLeaderError::NoClientInArea)?; - Ok(**c) - } - - pub async fn get_area_leader(&self, roomlobby: RoomLobby) -> Result { - match roomlobby { - RoomLobby::Room(room) => { - self.get_room_leader(room).await - }, - RoomLobby::Lobby(lobby) => { - self.get_lobby_leader(lobby).await - } - } - } - - pub async fn get_leader_by_client(&self, id: ClientId) -> Result { - let area = self.client_location - .read() - .await; - let area = area - .get(&id) - .ok_or(GetLeaderError::InvalidClient)?; - match area { - RoomLobby::Room(room) => { - self.get_room_leader(*room).await - }, - RoomLobby::Lobby(lobby) => { - self.get_lobby_leader(*lobby).await - } - } - } - - pub async fn get_clients_in_lobby(&self, lobby: LobbyId) -> Result, GetClientsError> { - Ok(self.lobbies - .get(lobby.0) - .ok_or(GetClientsError::InvalidArea)? - .read() - .await - .0 - .iter() - .filter_map(|client| { - client.map(|c| { - c - }) - }).collect()) - } - - pub async fn get_clients_in_room(&self, room: RoomId) -> Result, GetClientsError> { - Ok(self.rooms.get(room.0) - .ok_or(GetClientsError::InvalidArea)? - .as_ref() - .read() - .await - .ok_or(GetClientsError::InvalidArea)? - .0 - .iter() - .filter_map(|client| { - client.map(|c| { - c - }) - }).collect()) - } - - pub async fn get_local_client(&self, id: ClientId) -> Result { - let area = self.client_location - .read() - .await; - let area = area - .get(&id) - .ok_or(GetClientsError::InvalidClient)?; - match area { - RoomLobby::Room(room) => { - self.get_clients_in_room(*room) - .await - .map_err(|_| GetClientsError::InvalidArea)? - .into_iter() - .find(|c| c.client == id) - .ok_or(GetClientsError::InvalidClient) - }, - RoomLobby::Lobby(lobby) => { - self.get_clients_in_lobby(*lobby) - .await - .map_err(|_| GetClientsError::InvalidArea)? - .into_iter() - .find(|c| c.client == id) - .ok_or(GetClientsError::InvalidClient) - } - } - } - - pub async fn get_area(&self, id: ClientId) -> Result { - self.client_location - .read() - .await - .get(&id) - .ok_or(GetAreaError::InvalidClient) - .map(Clone::clone) - } - - pub async fn get_room(&self, id: ClientId) -> Result { - if let RoomLobby::Room(room) = self.client_location.read().await.get(&id).ok_or(GetAreaError::InvalidClient)? { - Ok(*room) - } - else { - Err(GetAreaError::NotInRoom) - } - } - - pub async fn get_lobby(&self, id: ClientId) -> Result { - if let RoomLobby::Lobby(lobby) = self.client_location.read().await.get(&id).ok_or(GetAreaError::InvalidClient)? { - Ok(*lobby) - } - else { - Err(GetAreaError::NotInLobby) - } - } - - pub async fn remove_client_from_area(&self, id: ClientId) -> Result<(), ClientRemovalError> { - fn remove_client(id: ClientId, client_list : &mut [Option; N]) { - client_list - .iter_mut() - .filter(|client| { - client.map_or(false, |c| { - c.client == id - }) - }) - .for_each(|client| { - *client = None - }); - } - - let area = self.client_location - .read() - .await; - let area = area - .get(&id) - .ok_or(ClientRemovalError::ClientNotInArea)?; - match area { - RoomLobby::Room(room) => { - let mut r = self.rooms.get(room.0) - .ok_or(ClientRemovalError::InvalidArea)? - .as_ref() - .write() - .await; - if let Some(r) = r.as_mut() { - remove_client(id, &mut r.0) - } - else { - return Err(ClientRemovalError::InvalidArea) - } - }, - RoomLobby::Lobby(lobby) => { - remove_client(id, &mut self.lobbies[lobby.0].write().await.0) - } - }; - - Ok(()) - } -} - - - - - - - - -#[cfg(test)] -mod test { - use super::*; - - #[async_std::test] - async fn test_add_client_to_lobby() { - let cl = ClientLocation::default(); - cl.add_client_to_lobby(ClientId(12), LobbyId(0)).await.unwrap(); - cl.add_client_to_lobby(ClientId(13), LobbyId(1)).await.unwrap(); - cl.add_client_to_lobby(ClientId(14), LobbyId(0)).await.unwrap(); - - assert!(cl.get_clients_in_lobby(LobbyId(0)).await.into_iter().flatten().map(|c| (c.client, c.local_client)).collect::>() == vec![ - (ClientId(12), LocalClientId(0)), - (ClientId(14), LocalClientId(1)), - ]); - } - - #[async_std::test] - async fn test_add_client_to_full_lobby() { - let cl = ClientLocation::default(); - for i in 0..12 { - cl.add_client_to_lobby(ClientId(i), LobbyId(0)).await.unwrap(); - } - assert!(cl.add_client_to_lobby(ClientId(99), LobbyId(0)).await == Err(JoinLobbyError::LobbyFull)); - } - - #[async_std::test] - async fn test_add_client_to_next_available_lobby() { - let cl = ClientLocation::default(); - for lobby in 1..4 { - for i in 0..12 { - cl.add_client_to_lobby(ClientId(lobby*12+i), LobbyId(lobby)).await.unwrap(); - } - } - assert!(cl.add_client_to_next_available_lobby(ClientId(99), LobbyId(1)).await == Ok(LobbyId(4))); - } - - #[async_std::test] - async fn test_add_to_lobby_when_all_are_full() { - let cl = ClientLocation::default(); - for lobby in 0..15 { - for i in 0..12 { - cl.add_client_to_lobby(ClientId(lobby*12+i), LobbyId(lobby)).await.unwrap(); - } - } - assert_eq!(cl.add_client_to_next_available_lobby(ClientId(99), LobbyId(1)).await, Err(JoinLobbyError::LobbyFull)); - } - - #[async_std::test] - async fn test_new_room() { - let mut cl = ClientLocation::default(); - assert!(cl.create_new_room(ClientId(12)).await == Ok(RoomId(0))); - } - - #[async_std::test] - async fn test_add_client_to_room() { - let mut cl = ClientLocation::default(); - let room = cl.create_new_room(ClientId(12)).await.unwrap(); - assert!(cl.add_client_to_room(ClientId(234), room).await == Ok(())); - assert!(cl.get_clients_in_room(room).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>() == vec![ - (ClientId(12), LocalClientId(0)), - (ClientId(234), LocalClientId(1)), - ]); - } - - #[async_std::test] - async fn test_no_new_room_slots() { - let mut cl = ClientLocation::default(); - for i in 0..128 { - cl.create_new_room(ClientId(i)).await; - } - assert!(cl.create_new_room(ClientId(234)).await == Err(CreateRoomError::NoOpenSlots)); - } - - #[async_std::test] - async fn test_joining_full_room() { - let mut cl = ClientLocation::default(); - let room = cl.create_new_room(ClientId(0)).await.unwrap(); - assert!(cl.add_client_to_room(ClientId(1), room).await == Ok(())); - assert!(cl.add_client_to_room(ClientId(2), room).await == Ok(())); - assert!(cl.add_client_to_room(ClientId(3), room).await == Ok(())); - assert!(cl.add_client_to_room(ClientId(234), room).await == Err(JoinRoomError::RoomFull)); - } - - #[async_std::test] - async fn test_adding_client_to_room_removes_from_lobby() { - let mut cl = ClientLocation::default(); - cl.add_client_to_lobby(ClientId(93), LobbyId(0)).await; - cl.add_client_to_lobby(ClientId(23), LobbyId(0)).await; - cl.add_client_to_lobby(ClientId(51), LobbyId(0)).await; - cl.add_client_to_lobby(ClientId(12), LobbyId(0)).await; - - let room = cl.create_new_room(ClientId(51)).await.unwrap(); - assert!(cl.add_client_to_room(ClientId(93), room).await == Ok(())); - assert!(cl.get_clients_in_lobby(LobbyId(0)).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>() == vec![ - (ClientId(23), LocalClientId(1)), - (ClientId(12), LocalClientId(3)), - ]); - assert!(cl.get_clients_in_room(room).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>() == vec![ - (ClientId(51), LocalClientId(0)), - (ClientId(93), LocalClientId(1)), - ]); - } - - #[async_std::test] - async fn test_getting_neighbors() { - let cl = ClientLocation::default(); - cl.add_client_to_lobby(ClientId(93), LobbyId(0)).await.unwrap(); - cl.add_client_to_lobby(ClientId(23), LobbyId(0)).await.unwrap(); - cl.add_client_to_lobby(ClientId(51), LobbyId(0)).await.unwrap(); - cl.add_client_to_lobby(ClientId(12), LobbyId(0)).await.unwrap(); - - assert!(cl.get_client_neighbors(ClientId(23)).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>() == vec![ - (ClientId(93), LocalClientId(0)), - (ClientId(51), LocalClientId(2)), - (ClientId(12), LocalClientId(3)), - ]); - } - - #[async_std::test] - async fn test_failing_to_join_lobby_does_not_remove_from_current_area() { - let cl = ClientLocation::default(); - for i in 0..12 { - cl.add_client_to_lobby(ClientId(i), LobbyId(0)).await.unwrap(); - } - assert!(cl.add_client_to_lobby(ClientId(99), LobbyId(1)).await.is_ok()); - assert!(cl.add_client_to_lobby(ClientId(99), LobbyId(0)).await.is_err()); - assert_eq!(cl.get_clients_in_lobby(LobbyId(0)).await.unwrap().len(), 12); - assert_eq!( - cl.get_clients_in_lobby(LobbyId(1)).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>(), - vec![(ClientId(99), LocalClientId(0))] - ); - } - - #[async_std::test] - async fn test_get_leader() { - let cl = ClientLocation::default(); - cl.add_client_to_lobby(ClientId(93), LobbyId(0)).await; - cl.add_client_to_lobby(ClientId(23), LobbyId(0)).await; - cl.add_client_to_lobby(ClientId(51), LobbyId(0)).await; - cl.add_client_to_lobby(ClientId(12), LobbyId(0)).await; - - assert!(cl.get_leader_by_client(ClientId(51)).await.map(|c| (c.client, c.local_client)) == Ok((ClientId(93), LocalClientId(0)))); - } - - #[async_std::test] - async fn test_remove_client_from_room() { - let mut cl = ClientLocation::default(); - let room = cl.create_new_room(ClientId(51)).await.unwrap(); - cl.add_client_to_room(ClientId(93), room).await; - cl.add_client_to_room(ClientId(23), room).await; - cl.remove_client_from_area(ClientId(51)).await; - cl.add_client_to_room(ClientId(12), room).await; - - assert!(cl.get_clients_in_room(room).await.unwrap().into_iter().map(|c| (c.client, c.local_client)).collect::>() == vec![ - (ClientId(12), LocalClientId(0)), - (ClientId(93), LocalClientId(1)), - (ClientId(23), LocalClientId(2)), - ]); - } - - #[async_std::test] - async fn test_leader_changes_on_leader_leaving() { - let mut cl = ClientLocation::default(); - let room = cl.create_new_room(ClientId(51)).await.unwrap(); - cl.add_client_to_room(ClientId(93), room).await.unwrap(); - cl.add_client_to_room(ClientId(23), room).await.unwrap(); - cl.remove_client_from_area(ClientId(51)).await.unwrap(); - cl.add_client_to_room(ClientId(12), room).await.unwrap(); - cl.remove_client_from_area(ClientId(23)).await.unwrap(); - cl.add_client_to_room(ClientId(99), room).await.unwrap(); - - assert!(cl.get_leader_by_client(ClientId(12)).await.map(|c| (c.client, c.local_client)) == Ok((ClientId(93), LocalClientId(1)))); - } -} diff --git a/quests/src/lib.rs b/quests/src/lib.rs index de40457..91e5d4d 100644 --- a/quests/src/lib.rs +++ b/quests/src/lib.rs @@ -1,4 +1,328 @@ -pub mod quests; +use log::warn; +use std::collections::{HashMap, BTreeMap, BTreeSet}; +use std::fs::File; +use std::io::{Read, Write, Cursor, Seek, SeekFrom}; +use std::path::PathBuf; +use std::convert::TryInto; +use async_std::sync::Arc; +use thiserror::Error; +use serde::{Serialize, Deserialize}; +use ages_prs::{LegacyPrsDecoder, LegacyPrsEncoder}; +use byteorder::{LittleEndian, ReadBytesExt}; +use libpso::util::array_to_utf16; +use maps::area::{MapArea, MapAreaError}; +use maps::object::MapObject; +use maps::enemy::MapEnemy; +use maps::maps::{objects_from_stream, enemy_data_from_stream}; +use maps::room::{Episode, RoomMode}; +use maps::area::{MapAreaLookup, MapAreaLookupBuilder}; -pub use quests::*; +#[derive(Debug, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct QuestCategory { + index: usize, + pub name: String, + pub description: String, +} + + +#[derive(Debug, Serialize, Deserialize, Hash)] +struct QuestListEntry { + bin: String, + dat: String, +} + +#[derive(Debug, Serialize, Deserialize, Hash)] +struct QuestListCategory { + list_order: usize, + description: String, + quests: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +struct QuestListConfig { + questlist: HashMap>, +} + +#[derive(Error, Debug)] +#[error("")] +pub enum ParseDatError { + IoError(#[from] std::io::Error), + MapError(#[from] MapAreaError), + UnknownDatHeader(u32), + CouldNotDetermineEpisode, + InvalidMapAreaId(u16), +} + +const DAT_OBJECT_HEADER_ID: u32 = 1; +const DAT_ENEMY_HEADER_ID: u32 = 2; +const DAT_WAVE_HEADER_ID: u32 = 3; + +enum DatBlock { + Object(Vec>), + Enemy(Vec>), + Wave, +} + + +fn read_dat_section_header(cursor: &mut T, episode: &Episode, map_areas: &MapAreaLookup) -> Result { + let header = cursor.read_u32::()?; + let _offset = cursor.read_u32::()?; + let area = cursor.read_u16::()?; + let _unknown1 = cursor.read_u16::()?; + let length = cursor.read_u32::()?; + + let map_area = map_areas.get_area_map(area).map_err(|_| ParseDatError::InvalidMapAreaId(area))?; + + match header { + DAT_OBJECT_HEADER_ID => { + let mut obj_data = vec![0u8; length as usize]; + cursor.read_exact(&mut obj_data)?; + let mut obj_cursor = Cursor::new(obj_data); + + let objects = objects_from_stream(&mut obj_cursor, episode, &map_area); + Ok(DatBlock::Object(objects)) + }, + DAT_ENEMY_HEADER_ID => { + let mut enemy_data = vec![0u8; length as usize]; + cursor.read_exact(&mut enemy_data)?; + let mut enemy_cursor = Cursor::new(enemy_data); + + let enemies = enemy_data_from_stream(&mut enemy_cursor, &map_area, episode); + + Ok(DatBlock::Enemy(enemies)) + }, + DAT_WAVE_HEADER_ID => { + cursor.seek(SeekFrom::Current(length as i64))?; + Ok(DatBlock::Wave) + }, + _ => Err(ParseDatError::UnknownDatHeader(header)) + } +} + +fn quest_episode(bin: &[u8]) -> Option { + for bytes in bin.windows(3) { + // set_episode + if bytes[0] == 0xF8 && bytes[1] == 0xBC { + return Episode::from_quest(bytes[2]) + } + } + None +} + +fn map_area_mappings(bin: &[u8]) -> MapAreaLookup { + let mut map_areas = MapAreaLookupBuilder::default(); + for bytes in bin.windows(4) { + // BB_Map_Designate + if bytes[0] == 0xF9 && bytes[1] == 0x51 { + //return Some(Episode::from_quest(bytes[2]).ok()?) + let floor_value = bytes[2] as u16; + if let Some(map_area) = MapArea::from_bb_map_designate(bytes[3]) { + map_areas = map_areas.add(floor_value, map_area); + } + } + } + map_areas.build() +} + +#[allow(clippy::type_complexity)] +fn parse_dat(dat: &[u8], episode: &Episode, map_areas: &MapAreaLookup) -> Result<(Vec>, Vec>), ParseDatError> { + let mut cursor = Cursor::new(dat); + + let header_iter = std::iter::from_fn(move || { + match read_dat_section_header(&mut cursor, episode, map_areas) { + Ok(dat_block) => Some(dat_block), + Err(err) => { + warn!("unknown header in dat: {:?}", err); + None + } + } + }); + + Ok(header_iter.fold((Vec::new(), Vec::new()), |(mut enemies, mut objects), dat_block| { + match dat_block { + DatBlock::Object(mut objs) => { + objects.append(&mut objs) + }, + DatBlock::Enemy(mut enemy) => { + enemies.append(&mut enemy) + }, + _ => {} + } + + (enemies, objects) + })) +} + +#[derive(Error, Debug)] +pub enum QuestLoadError { + #[error("io error {0}")] + IoError(#[from] std::io::Error), + #[error("parse dat error {0}")] + ParseDatError(#[from] ParseDatError), + #[error("could not read metadata")] + CouldNotReadMetadata, + #[error("could not load config file")] + CouldNotLoadConfigFile, +} + +#[derive(Debug, Clone)] +pub struct Quest { + pub name: String, + pub description: String, + pub full_description: String, + pub language: u16, + pub id: u16, + pub bin_blob: Arc>, + pub dat_blob: Arc>, + pub enemies: Vec>, // TODO: Arc? + pub objects: Vec>, // TODO: Arc? + pub map_areas: MapAreaLookup, // TODO: Arc? +} + +impl Quest { + fn from_bin_dat(bin: Vec, dat: Vec) -> Result { + let id = u16::from_le_bytes(bin[16..18].try_into().map_err(|_| QuestLoadError::CouldNotReadMetadata)?); + let language = u16::from_le_bytes(bin[18..20].try_into().map_err(|_| QuestLoadError::CouldNotReadMetadata)?); + let name = array_to_utf16(&bin[24..88]); + let description = array_to_utf16(&bin[88..334]); + let full_description = array_to_utf16(&bin[334..920]); + + let episode = quest_episode(&bin).ok_or(ParseDatError::CouldNotDetermineEpisode)?; + let map_areas = map_area_mappings(&bin); + let (enemies, objects) = parse_dat(&dat, &episode, &map_areas)?; + + let mut prs_bin = LegacyPrsEncoder::new(Vec::new()); + prs_bin.write_all(&bin)?; + let mut prs_dat = LegacyPrsEncoder::new(Vec::new()); + prs_dat.write_all(&dat)?; + + Ok(Quest { + name, + description, + full_description, + id, + language, + bin_blob: Arc::new(prs_bin.into_inner().map_err(|_| QuestLoadError::CouldNotReadMetadata)?), + dat_blob: Arc::new(prs_dat.into_inner().map_err(|_| QuestLoadError::CouldNotReadMetadata)?), + enemies, + objects, + map_areas, + }) + } +} + +// QuestCollection +pub type QuestList = BTreeMap>; + +pub fn load_quest(bin_path: PathBuf, dat_path: PathBuf, quest_path: PathBuf) -> Option { + let dat_file = File::open(quest_path.join(dat_path.clone())) + .map_err(|err| { + warn!("could not load quest file {:?}: {:?}", dat_path, err) + }).ok()?; + let bin_file = File::open(quest_path.join(bin_path.clone())) + .map_err(|err| { + warn!("could not load quest file {:?}: {:?}", bin_path, err) + }).ok()?; + let mut dat_prs = LegacyPrsDecoder::new(dat_file); + let mut bin_prs = LegacyPrsDecoder::new(bin_file); + + let mut dat = Vec::new(); + let mut bin = Vec::new(); + dat_prs.read_to_end(&mut dat).ok()?; + bin_prs.read_to_end(&mut bin).ok()?; + + let quest = Quest::from_bin_dat(bin, dat).map_err(|err| { + warn!("could not parse quest file {:?}/{:?}: {:?}", bin_path, dat_path, err) + }).ok()?; + Some(quest) +} + + +pub fn load_quests_path(mut quest_path: PathBuf) -> Result { + let mut f = File::open(quest_path.clone()).map_err(|_| QuestLoadError::CouldNotLoadConfigFile)?; + let mut s = String::new(); + f.read_to_string(&mut s)?; + quest_path.pop(); // remove quests.toml from the path + let mut used_quest_ids = BTreeSet::new(); + let ql: BTreeMap = toml::from_str(s.as_str()).map_err(|_| QuestLoadError::CouldNotLoadConfigFile)?; + + Ok(ql.into_iter().map(|(category, category_details)| { + ( + QuestCategory { + index: category_details.list_order, + name: category, + description: category_details.description, + }, + category_details.quests + .into_iter() + .filter_map(|quest| { + load_quest(quest.bin.into(), quest.dat.into(), quest_path.to_path_buf()) + .and_then(|quest | { + if used_quest_ids.contains(&quest.id) { + warn!("quest id already exists: {}", quest.id); + return None; + } + used_quest_ids.insert(quest.id); + Some(quest) + }) + }) + .collect() + ) + }).collect()) +} + +pub fn load_standard_quests(mode: RoomMode) -> Result { + match mode { + RoomMode::Single {episode, .. } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "single", "quests.toml"])) + }, + RoomMode::Multi {episode, .. } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "multi", "quests.toml"])) + }, + _ => { + Ok(BTreeMap::new()) + } + } +} + + +pub fn load_government_quests(mode: RoomMode) -> Result { + match mode { + RoomMode::Single {episode, .. } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "government", "quests.toml"])) + }, + RoomMode::Multi {episode, .. } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "government", "quests.toml"])) + }, + _ => { + Ok(BTreeMap::new()) + } + } +} + + + + + + +#[cfg(test)] +mod tests { + use super::*; + + // the quest phantasmal world 4 uses the tower map twice, to do this it had to remap + // one of the other maps to be a second tower + #[test] + fn test_quest_with_remapped_floors() { + let pw4 = load_quest("q236-ext-bb.bin".into(), "q236-ext-bb.dat".into(), "data/quests/bb/ep2/multi".into()).unwrap(); + let enemies_not_in_tower = pw4.enemies.iter() + .filter(|enemy| { + enemy.is_some() + }) + .filter(|enemy| { + enemy.unwrap().map_area != MapArea::Tower + }); + assert!(enemies_not_in_tower.count() == 0); + + } +} diff --git a/quests/src/quests.rs b/quests/src/quests.rs deleted file mode 100644 index 91e5d4d..0000000 --- a/quests/src/quests.rs +++ /dev/null @@ -1,328 +0,0 @@ -use log::warn; -use std::collections::{HashMap, BTreeMap, BTreeSet}; -use std::fs::File; -use std::io::{Read, Write, Cursor, Seek, SeekFrom}; -use std::path::PathBuf; -use std::convert::TryInto; -use async_std::sync::Arc; -use thiserror::Error; -use serde::{Serialize, Deserialize}; -use ages_prs::{LegacyPrsDecoder, LegacyPrsEncoder}; -use byteorder::{LittleEndian, ReadBytesExt}; -use libpso::util::array_to_utf16; -use maps::area::{MapArea, MapAreaError}; -use maps::object::MapObject; -use maps::enemy::MapEnemy; -use maps::maps::{objects_from_stream, enemy_data_from_stream}; -use maps::room::{Episode, RoomMode}; -use maps::area::{MapAreaLookup, MapAreaLookupBuilder}; - - -#[derive(Debug, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)] -pub struct QuestCategory { - index: usize, - pub name: String, - pub description: String, -} - - -#[derive(Debug, Serialize, Deserialize, Hash)] -struct QuestListEntry { - bin: String, - dat: String, -} - -#[derive(Debug, Serialize, Deserialize, Hash)] -struct QuestListCategory { - list_order: usize, - description: String, - quests: Vec, -} - -#[derive(Debug, Serialize, Deserialize)] -struct QuestListConfig { - questlist: HashMap>, -} - -#[derive(Error, Debug)] -#[error("")] -pub enum ParseDatError { - IoError(#[from] std::io::Error), - MapError(#[from] MapAreaError), - UnknownDatHeader(u32), - CouldNotDetermineEpisode, - InvalidMapAreaId(u16), -} - -const DAT_OBJECT_HEADER_ID: u32 = 1; -const DAT_ENEMY_HEADER_ID: u32 = 2; -const DAT_WAVE_HEADER_ID: u32 = 3; - -enum DatBlock { - Object(Vec>), - Enemy(Vec>), - Wave, -} - - -fn read_dat_section_header(cursor: &mut T, episode: &Episode, map_areas: &MapAreaLookup) -> Result { - let header = cursor.read_u32::()?; - let _offset = cursor.read_u32::()?; - let area = cursor.read_u16::()?; - let _unknown1 = cursor.read_u16::()?; - let length = cursor.read_u32::()?; - - let map_area = map_areas.get_area_map(area).map_err(|_| ParseDatError::InvalidMapAreaId(area))?; - - match header { - DAT_OBJECT_HEADER_ID => { - let mut obj_data = vec![0u8; length as usize]; - cursor.read_exact(&mut obj_data)?; - let mut obj_cursor = Cursor::new(obj_data); - - let objects = objects_from_stream(&mut obj_cursor, episode, &map_area); - Ok(DatBlock::Object(objects)) - }, - DAT_ENEMY_HEADER_ID => { - let mut enemy_data = vec![0u8; length as usize]; - cursor.read_exact(&mut enemy_data)?; - let mut enemy_cursor = Cursor::new(enemy_data); - - let enemies = enemy_data_from_stream(&mut enemy_cursor, &map_area, episode); - - Ok(DatBlock::Enemy(enemies)) - }, - DAT_WAVE_HEADER_ID => { - cursor.seek(SeekFrom::Current(length as i64))?; - Ok(DatBlock::Wave) - }, - _ => Err(ParseDatError::UnknownDatHeader(header)) - } -} - -fn quest_episode(bin: &[u8]) -> Option { - for bytes in bin.windows(3) { - // set_episode - if bytes[0] == 0xF8 && bytes[1] == 0xBC { - return Episode::from_quest(bytes[2]) - } - } - None -} - -fn map_area_mappings(bin: &[u8]) -> MapAreaLookup { - let mut map_areas = MapAreaLookupBuilder::default(); - for bytes in bin.windows(4) { - // BB_Map_Designate - if bytes[0] == 0xF9 && bytes[1] == 0x51 { - //return Some(Episode::from_quest(bytes[2]).ok()?) - let floor_value = bytes[2] as u16; - if let Some(map_area) = MapArea::from_bb_map_designate(bytes[3]) { - map_areas = map_areas.add(floor_value, map_area); - } - } - } - map_areas.build() -} - -#[allow(clippy::type_complexity)] -fn parse_dat(dat: &[u8], episode: &Episode, map_areas: &MapAreaLookup) -> Result<(Vec>, Vec>), ParseDatError> { - let mut cursor = Cursor::new(dat); - - let header_iter = std::iter::from_fn(move || { - match read_dat_section_header(&mut cursor, episode, map_areas) { - Ok(dat_block) => Some(dat_block), - Err(err) => { - warn!("unknown header in dat: {:?}", err); - None - } - } - }); - - Ok(header_iter.fold((Vec::new(), Vec::new()), |(mut enemies, mut objects), dat_block| { - match dat_block { - DatBlock::Object(mut objs) => { - objects.append(&mut objs) - }, - DatBlock::Enemy(mut enemy) => { - enemies.append(&mut enemy) - }, - _ => {} - } - - (enemies, objects) - })) -} - -#[derive(Error, Debug)] -pub enum QuestLoadError { - #[error("io error {0}")] - IoError(#[from] std::io::Error), - #[error("parse dat error {0}")] - ParseDatError(#[from] ParseDatError), - #[error("could not read metadata")] - CouldNotReadMetadata, - #[error("could not load config file")] - CouldNotLoadConfigFile, -} - -#[derive(Debug, Clone)] -pub struct Quest { - pub name: String, - pub description: String, - pub full_description: String, - pub language: u16, - pub id: u16, - pub bin_blob: Arc>, - pub dat_blob: Arc>, - pub enemies: Vec>, // TODO: Arc? - pub objects: Vec>, // TODO: Arc? - pub map_areas: MapAreaLookup, // TODO: Arc? -} - -impl Quest { - fn from_bin_dat(bin: Vec, dat: Vec) -> Result { - let id = u16::from_le_bytes(bin[16..18].try_into().map_err(|_| QuestLoadError::CouldNotReadMetadata)?); - let language = u16::from_le_bytes(bin[18..20].try_into().map_err(|_| QuestLoadError::CouldNotReadMetadata)?); - let name = array_to_utf16(&bin[24..88]); - let description = array_to_utf16(&bin[88..334]); - let full_description = array_to_utf16(&bin[334..920]); - - let episode = quest_episode(&bin).ok_or(ParseDatError::CouldNotDetermineEpisode)?; - let map_areas = map_area_mappings(&bin); - let (enemies, objects) = parse_dat(&dat, &episode, &map_areas)?; - - let mut prs_bin = LegacyPrsEncoder::new(Vec::new()); - prs_bin.write_all(&bin)?; - let mut prs_dat = LegacyPrsEncoder::new(Vec::new()); - prs_dat.write_all(&dat)?; - - Ok(Quest { - name, - description, - full_description, - id, - language, - bin_blob: Arc::new(prs_bin.into_inner().map_err(|_| QuestLoadError::CouldNotReadMetadata)?), - dat_blob: Arc::new(prs_dat.into_inner().map_err(|_| QuestLoadError::CouldNotReadMetadata)?), - enemies, - objects, - map_areas, - }) - } -} - -// QuestCollection -pub type QuestList = BTreeMap>; - -pub fn load_quest(bin_path: PathBuf, dat_path: PathBuf, quest_path: PathBuf) -> Option { - let dat_file = File::open(quest_path.join(dat_path.clone())) - .map_err(|err| { - warn!("could not load quest file {:?}: {:?}", dat_path, err) - }).ok()?; - let bin_file = File::open(quest_path.join(bin_path.clone())) - .map_err(|err| { - warn!("could not load quest file {:?}: {:?}", bin_path, err) - }).ok()?; - let mut dat_prs = LegacyPrsDecoder::new(dat_file); - let mut bin_prs = LegacyPrsDecoder::new(bin_file); - - let mut dat = Vec::new(); - let mut bin = Vec::new(); - dat_prs.read_to_end(&mut dat).ok()?; - bin_prs.read_to_end(&mut bin).ok()?; - - let quest = Quest::from_bin_dat(bin, dat).map_err(|err| { - warn!("could not parse quest file {:?}/{:?}: {:?}", bin_path, dat_path, err) - }).ok()?; - Some(quest) -} - - -pub fn load_quests_path(mut quest_path: PathBuf) -> Result { - let mut f = File::open(quest_path.clone()).map_err(|_| QuestLoadError::CouldNotLoadConfigFile)?; - let mut s = String::new(); - f.read_to_string(&mut s)?; - quest_path.pop(); // remove quests.toml from the path - let mut used_quest_ids = BTreeSet::new(); - let ql: BTreeMap = toml::from_str(s.as_str()).map_err(|_| QuestLoadError::CouldNotLoadConfigFile)?; - - Ok(ql.into_iter().map(|(category, category_details)| { - ( - QuestCategory { - index: category_details.list_order, - name: category, - description: category_details.description, - }, - category_details.quests - .into_iter() - .filter_map(|quest| { - load_quest(quest.bin.into(), quest.dat.into(), quest_path.to_path_buf()) - .and_then(|quest | { - if used_quest_ids.contains(&quest.id) { - warn!("quest id already exists: {}", quest.id); - return None; - } - used_quest_ids.insert(quest.id); - Some(quest) - }) - }) - .collect() - ) - }).collect()) -} - -pub fn load_standard_quests(mode: RoomMode) -> Result { - match mode { - RoomMode::Single {episode, .. } => { - load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "single", "quests.toml"])) - }, - RoomMode::Multi {episode, .. } => { - load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "multi", "quests.toml"])) - }, - _ => { - Ok(BTreeMap::new()) - } - } -} - - -pub fn load_government_quests(mode: RoomMode) -> Result { - match mode { - RoomMode::Single {episode, .. } => { - load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "government", "quests.toml"])) - }, - RoomMode::Multi {episode, .. } => { - load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "government", "quests.toml"])) - }, - _ => { - Ok(BTreeMap::new()) - } - } -} - - - - - - -#[cfg(test)] -mod tests { - use super::*; - - // the quest phantasmal world 4 uses the tower map twice, to do this it had to remap - // one of the other maps to be a second tower - #[test] - fn test_quest_with_remapped_floors() { - let pw4 = load_quest("q236-ext-bb.bin".into(), "q236-ext-bb.dat".into(), "data/quests/bb/ep2/multi".into()).unwrap(); - let enemies_not_in_tower = pw4.enemies.iter() - .filter(|enemy| { - enemy.is_some() - }) - .filter(|enemy| { - enemy.unwrap().map_area != MapArea::Tower - }); - assert!(enemies_not_in_tower.count() == 0); - - } -} diff --git a/room/src/lib.rs b/room/src/lib.rs index 4f8d063..5110d22 100644 --- a/room/src/lib.rs +++ b/room/src/lib.rs @@ -1,3 +1,272 @@ -pub mod room; +use std::collections::HashMap; +use std::convert::{From, Into}; +use async_std::sync::{Arc, RwLock, RwLockReadGuard}; +use futures::future::BoxFuture; +use futures::stream::{FuturesOrdered, Stream}; -pub use room::*; +use thiserror::Error; +use rand::Rng; + +use maps::maps::Maps; +use drops::DropTable; +use entity::character::SectionID; +use entity::room::{RoomEntityId, RoomEntityMode}; +use maps::monster::{load_monster_stats_table, MonsterType, MonsterStats}; +use maps::area::MapAreaLookup; +use quests; +use maps::Holiday; +use location::{MAX_ROOMS, RoomId}; + +use maps::room::{Episode, Difficulty, RoomMode}; + +#[derive(Error, Debug)] +pub enum RoomError { + #[error("invalid room id {0}")] + Invalid(u32), +} + + +#[derive(Clone)] +pub struct Rooms([Arc>>; MAX_ROOMS]); + + +impl Default for Rooms { + fn default() -> Rooms { + Rooms(core::array::from_fn(|_| Arc::new(RwLock::new(None)))) + } +} + +impl Rooms { + pub async fn add(&self, room_id: RoomId, room: RoomState) -> Result<(), anyhow::Error> { + *self.0 + .get(room_id.0) + .ok_or(RoomError::Invalid(room_id.0 as u32))? + .write() + .await = Some(room); + Ok(()) + } + + pub async fn remove(&self, room_id: RoomId) { + if let Some(room) = self.0.get(room_id.0) { + *room + .write() + .await = None; + } + } + + pub async fn exists(&self, room_id: RoomId) -> bool { + match self.0.get(room_id.0) { + Some(room) => { + room + .read() + .await + .is_some() + }, + None => false, + } + } + + pub async fn with<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result + where + T: Send, + F: for<'b> FnOnce(&'b RoomState) -> BoxFuture<'b, T> + Send + 'a + { + let room = self.0 + .get(room_id.0) + .ok_or(RoomError::Invalid(room_id.0 as u32))? + .read() + .await; + if let Some(room) = room.as_ref() { + Ok(func(room).await) + } + else { + Err(RoomError::Invalid(room_id.0 as u32).into()) + } + } + + pub async fn with_mut<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result + where + T: Send, + F: for<'b> FnOnce(&'b mut RoomState) -> BoxFuture<'b, T> + Send + 'a + { + let mut room = self.0 + .get(room_id.0) + .ok_or(RoomError::Invalid(room_id.0 as u32))? + .write() + .await; + + if let Some(room) = room.as_mut() { + Ok(func(room).await) + } + else { + Err(RoomError::Invalid(room_id.0 as u32).into()) + } + } + + pub async fn get(&self, room_id: RoomId) -> RwLockReadGuard> { + self.0 + .get(room_id.0) + .unwrap() + .read() + .await + } + + pub fn stream(&self) -> impl Stream>> { + self.0 + .iter() + .map(|room| async move { + room + .read() + .await + }) + .collect::>() + } +} + +#[derive(Debug, Error)] +#[error("")] +pub enum RoomCreationError { + InvalidMode, + InvalidEpisode(u8), + InvalidDifficulty(u8), + CouldNotLoadMonsterStats(RoomMode), + CouldNotLoadQuests, +} + + +pub enum QuestCategoryType { + Standard, + Government, +} + +impl From for QuestCategoryType { + fn from(f: usize) -> QuestCategoryType { + match f { + 0 => QuestCategoryType::Standard, + _ => QuestCategoryType::Government, + } + } +} +impl From for QuestCategoryType { + fn from(f: u32) -> QuestCategoryType { + match f { + 0 => QuestCategoryType::Standard, + _ => QuestCategoryType::Government, + } + } +} + +impl QuestCategoryType { + pub fn value(&self) -> usize { + match self { + QuestCategoryType::Standard => 0, + QuestCategoryType::Government => 1, + } + } +} + +pub struct RoomState { + pub room_id: RoomEntityId, + pub mode: RoomMode, + pub name: String, + pub password: [u16; 16], + pub maps: Maps, + pub drop_table: Box, + pub section_id: SectionID, + pub random_seed: u32, + pub bursting: bool, + pub monster_stats: Box>, + pub map_areas: MapAreaLookup, + pub quest_group: QuestCategoryType, + pub standard_quests: quests::QuestList, + pub government_quests: quests::QuestList, + // enemy info +} + +impl RoomState { + pub fn get_flags_for_room_list(&self) -> u8 { + let mut flags = 0u8; + + match self.mode { + RoomMode::Single {..} => {flags += 0x04} + RoomMode::Battle {..} => {flags += 0x10}, + RoomMode::Challenge {..} => {flags += 0x20}, + _ => {flags += 0x40}, + }; + + if self.password[0] > 0 { + flags += 0x02; + } + flags + } + + pub fn get_episode_for_room_list(&self) -> u8 { + let episode: u8 = self.mode.episode().into(); + + match self.mode { + RoomMode::Single {..} => episode + 0x10, + _ => episode + 0x40, + } + } + + pub fn get_difficulty_for_room_list(&self) -> u8 { + let difficulty: u8 = self.mode.difficulty().into(); + difficulty + 0x22 + } + + pub fn quests(&self) -> &quests::QuestList { + match self.quest_group { + QuestCategoryType::Standard => &self.standard_quests, + QuestCategoryType::Government => &self.government_quests, + } + } + + #[allow(clippy::too_many_arguments, clippy::type_complexity)] + pub fn new (room_id: RoomEntityId, + mode: RoomEntityMode, + episode: Episode, + difficulty: Difficulty, + section_id: SectionID, + name: String, + password: [u16; 16], + event: Holiday, + map_builder: Arc Maps + Send + Sync>>, + drop_table_builder: Arc DropTable + Send + Sync>>, + ) -> Result { + let mode = match mode { + RoomEntityMode::Single => RoomMode::Single { + episode, + difficulty, + }, + RoomEntityMode::Multi => RoomMode::Multi { + episode, + difficulty, + }, + RoomEntityMode::Challenge => RoomMode::Challenge { + episode, + }, + RoomEntityMode::Battle => RoomMode::Battle { + episode, + difficulty, + }, + }; + + Ok(RoomState { + room_id, + monster_stats: Box::new(load_monster_stats_table(&mode).map_err(|_| RoomCreationError::CouldNotLoadMonsterStats(mode))?), + mode, + random_seed: rand::thread_rng().gen(), + name, + password, + maps: map_builder(mode, event), + section_id, + drop_table: Box::new(drop_table_builder(episode, difficulty, section_id)), + bursting: false, + map_areas: MapAreaLookup::new(&episode), + quest_group: QuestCategoryType::Standard, + standard_quests: quests::load_standard_quests(mode)?, + government_quests: quests::load_government_quests(mode)?, + }) + + } +} diff --git a/room/src/room.rs b/room/src/room.rs deleted file mode 100644 index 5110d22..0000000 --- a/room/src/room.rs +++ /dev/null @@ -1,272 +0,0 @@ -use std::collections::HashMap; -use std::convert::{From, Into}; -use async_std::sync::{Arc, RwLock, RwLockReadGuard}; -use futures::future::BoxFuture; -use futures::stream::{FuturesOrdered, Stream}; - -use thiserror::Error; -use rand::Rng; - -use maps::maps::Maps; -use drops::DropTable; -use entity::character::SectionID; -use entity::room::{RoomEntityId, RoomEntityMode}; -use maps::monster::{load_monster_stats_table, MonsterType, MonsterStats}; -use maps::area::MapAreaLookup; -use quests; -use maps::Holiday; -use location::{MAX_ROOMS, RoomId}; - -use maps::room::{Episode, Difficulty, RoomMode}; - -#[derive(Error, Debug)] -pub enum RoomError { - #[error("invalid room id {0}")] - Invalid(u32), -} - - -#[derive(Clone)] -pub struct Rooms([Arc>>; MAX_ROOMS]); - - -impl Default for Rooms { - fn default() -> Rooms { - Rooms(core::array::from_fn(|_| Arc::new(RwLock::new(None)))) - } -} - -impl Rooms { - pub async fn add(&self, room_id: RoomId, room: RoomState) -> Result<(), anyhow::Error> { - *self.0 - .get(room_id.0) - .ok_or(RoomError::Invalid(room_id.0 as u32))? - .write() - .await = Some(room); - Ok(()) - } - - pub async fn remove(&self, room_id: RoomId) { - if let Some(room) = self.0.get(room_id.0) { - *room - .write() - .await = None; - } - } - - pub async fn exists(&self, room_id: RoomId) -> bool { - match self.0.get(room_id.0) { - Some(room) => { - room - .read() - .await - .is_some() - }, - None => false, - } - } - - pub async fn with<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result - where - T: Send, - F: for<'b> FnOnce(&'b RoomState) -> BoxFuture<'b, T> + Send + 'a - { - let room = self.0 - .get(room_id.0) - .ok_or(RoomError::Invalid(room_id.0 as u32))? - .read() - .await; - if let Some(room) = room.as_ref() { - Ok(func(room).await) - } - else { - Err(RoomError::Invalid(room_id.0 as u32).into()) - } - } - - pub async fn with_mut<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result - where - T: Send, - F: for<'b> FnOnce(&'b mut RoomState) -> BoxFuture<'b, T> + Send + 'a - { - let mut room = self.0 - .get(room_id.0) - .ok_or(RoomError::Invalid(room_id.0 as u32))? - .write() - .await; - - if let Some(room) = room.as_mut() { - Ok(func(room).await) - } - else { - Err(RoomError::Invalid(room_id.0 as u32).into()) - } - } - - pub async fn get(&self, room_id: RoomId) -> RwLockReadGuard> { - self.0 - .get(room_id.0) - .unwrap() - .read() - .await - } - - pub fn stream(&self) -> impl Stream>> { - self.0 - .iter() - .map(|room| async move { - room - .read() - .await - }) - .collect::>() - } -} - -#[derive(Debug, Error)] -#[error("")] -pub enum RoomCreationError { - InvalidMode, - InvalidEpisode(u8), - InvalidDifficulty(u8), - CouldNotLoadMonsterStats(RoomMode), - CouldNotLoadQuests, -} - - -pub enum QuestCategoryType { - Standard, - Government, -} - -impl From for QuestCategoryType { - fn from(f: usize) -> QuestCategoryType { - match f { - 0 => QuestCategoryType::Standard, - _ => QuestCategoryType::Government, - } - } -} -impl From for QuestCategoryType { - fn from(f: u32) -> QuestCategoryType { - match f { - 0 => QuestCategoryType::Standard, - _ => QuestCategoryType::Government, - } - } -} - -impl QuestCategoryType { - pub fn value(&self) -> usize { - match self { - QuestCategoryType::Standard => 0, - QuestCategoryType::Government => 1, - } - } -} - -pub struct RoomState { - pub room_id: RoomEntityId, - pub mode: RoomMode, - pub name: String, - pub password: [u16; 16], - pub maps: Maps, - pub drop_table: Box, - pub section_id: SectionID, - pub random_seed: u32, - pub bursting: bool, - pub monster_stats: Box>, - pub map_areas: MapAreaLookup, - pub quest_group: QuestCategoryType, - pub standard_quests: quests::QuestList, - pub government_quests: quests::QuestList, - // enemy info -} - -impl RoomState { - pub fn get_flags_for_room_list(&self) -> u8 { - let mut flags = 0u8; - - match self.mode { - RoomMode::Single {..} => {flags += 0x04} - RoomMode::Battle {..} => {flags += 0x10}, - RoomMode::Challenge {..} => {flags += 0x20}, - _ => {flags += 0x40}, - }; - - if self.password[0] > 0 { - flags += 0x02; - } - flags - } - - pub fn get_episode_for_room_list(&self) -> u8 { - let episode: u8 = self.mode.episode().into(); - - match self.mode { - RoomMode::Single {..} => episode + 0x10, - _ => episode + 0x40, - } - } - - pub fn get_difficulty_for_room_list(&self) -> u8 { - let difficulty: u8 = self.mode.difficulty().into(); - difficulty + 0x22 - } - - pub fn quests(&self) -> &quests::QuestList { - match self.quest_group { - QuestCategoryType::Standard => &self.standard_quests, - QuestCategoryType::Government => &self.government_quests, - } - } - - #[allow(clippy::too_many_arguments, clippy::type_complexity)] - pub fn new (room_id: RoomEntityId, - mode: RoomEntityMode, - episode: Episode, - difficulty: Difficulty, - section_id: SectionID, - name: String, - password: [u16; 16], - event: Holiday, - map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, - ) -> Result { - let mode = match mode { - RoomEntityMode::Single => RoomMode::Single { - episode, - difficulty, - }, - RoomEntityMode::Multi => RoomMode::Multi { - episode, - difficulty, - }, - RoomEntityMode::Challenge => RoomMode::Challenge { - episode, - }, - RoomEntityMode::Battle => RoomMode::Battle { - episode, - difficulty, - }, - }; - - Ok(RoomState { - room_id, - monster_stats: Box::new(load_monster_stats_table(&mode).map_err(|_| RoomCreationError::CouldNotLoadMonsterStats(mode))?), - mode, - random_seed: rand::thread_rng().gen(), - name, - password, - maps: map_builder(mode, event), - section_id, - drop_table: Box::new(drop_table_builder(episode, difficulty, section_id)), - bursting: false, - map_areas: MapAreaLookup::new(&episode), - quest_group: QuestCategoryType::Standard, - standard_quests: quests::load_standard_quests(mode)?, - government_quests: quests::load_government_quests(mode)?, - }) - - } -} diff --git a/trade/src/lib.rs b/trade/src/lib.rs index 2629bda..a6a7b18 100644 --- a/trade/src/lib.rs +++ b/trade/src/lib.rs @@ -1,4 +1,132 @@ -pub mod trade; +use std::collections::HashMap; +use networking::serverstate::ClientId; +use items; +use async_std::sync::{Arc, Mutex, MutexGuard}; +use futures::future::{Future, OptionFuture}; +use items::trade::TradeItem; +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum TradeStatus { + SentRequest, + ReceivedRequest, + Trading, + Confirmed, + FinalConfirm, + ItemsChecked, + TradeComplete, +} -pub use trade::*; + +#[derive(Debug, Clone)] +pub struct ClientTradeState { + client: ClientId, + other_client: ClientId, + pub items: Vec, + pub meseta: usize, + pub status: TradeStatus, +} + + +impl ClientTradeState { + pub fn client(&self) -> ClientId { + self.client + } + + pub fn other_client(&self) -> ClientId { + self.other_client + } +} + +#[derive(thiserror::Error, Debug)] +pub enum TradeStateError { + #[error("client not in trade {0}")] + ClientNotInTrade(ClientId), + #[error("mismatched trade {0} {1}")] + MismatchedTrade(ClientId, ClientId), +} + +#[derive(Default, Debug, Clone)] +pub struct TradeState { + trades: HashMap>>, +} + +impl TradeState { + pub fn new_trade(&mut self, sender: &ClientId, receiver: &ClientId) { + let state = ClientTradeState { + client: *sender, + other_client: *receiver, + items: Default::default(), + meseta: 0, + status: TradeStatus::SentRequest, + }; + self.trades.insert(*sender, Arc::new(Mutex::new(state))); + + let state = ClientTradeState { + client: *receiver, + other_client: *sender, + items: Default::default(), + meseta: 0, + status: TradeStatus::ReceivedRequest, + }; + self.trades.insert(*receiver, Arc::new(Mutex::new(state))); + } + + pub fn in_trade(&self, client: &ClientId) -> bool { + self.trades.contains_key(client) + } + + /* + pub async fn with<'a, T, F, Fut> (&'a self, client: &ClientId, func: F) -> Result + where + F: FnOnce(MutexGuard<'a, ClientTradeState>, MutexGuard<'a, ClientTradeState>) -> Fut + 'a, + Fut: Future + { + let c1 = self.trades.get(client).ok_or(TradeStateError::ClientNotInTrade(*client))?.lock().await; + let c2 = self.trades.get(&c1.other_client).ok_or(TradeStateError::ClientNotInTrade(c1.other_client))?.lock().await; + + // sanity check + if c1.client != c2.other_client { + return Err(TradeStateError::MismatchedTrade(c1.client, c2.client)); + } + Ok(func(c1, c2).await) + } + */ + pub async fn with<'a, T, F, Fut> (&'a self, client: &ClientId, func: F) -> Result + where + T: Send, + //F: for<'b> FnOnce(&'b mut ClientTradeState, &'b mut ClientTradeState) -> BoxFuture<'b, T> + Send + 'a + //F: for<'b> FnOnce(&'b mut ClientTradeState, &'b mut ClientTradeState) -> Fut + Send + 'a, + F: FnOnce(MutexGuard<'a, ClientTradeState>, MutexGuard<'a, ClientTradeState>) -> Fut + 'a, + Fut: Future, + { + let c1 = self.trades + .get(client) + .ok_or(TradeStateError::ClientNotInTrade(*client))? + .lock() + .await; + let c2 = self.trades + .get(&c1.other_client) + .ok_or(TradeStateError::ClientNotInTrade(c1.other_client))? + .lock() + .await; + + if c1.client != c2.other_client { + return Err(TradeStateError::MismatchedTrade(c1.client, c2.client)); + } + + Ok(func(c1, c2).await) + } + + // TODO: is it possible for this to not return Options? + pub async fn remove_trade(&mut self, client: &ClientId) -> (Option, Option) { + let c1 = OptionFuture::from(self.trades.remove(client).map(|c| async move {c.lock().await.clone()} )).await; + let c2 = if let Some(ref state) = c1 { + OptionFuture::from(self.trades.remove(&state.other_client).map(|c| async move {c.lock().await.clone()})).await + } + else { + None + }; + + (c1, c2) + } +} diff --git a/trade/src/trade.rs b/trade/src/trade.rs deleted file mode 100644 index a6a7b18..0000000 --- a/trade/src/trade.rs +++ /dev/null @@ -1,132 +0,0 @@ -use std::collections::HashMap; -use networking::serverstate::ClientId; -use items; -use async_std::sync::{Arc, Mutex, MutexGuard}; -use futures::future::{Future, OptionFuture}; -use items::trade::TradeItem; - -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum TradeStatus { - SentRequest, - ReceivedRequest, - Trading, - Confirmed, - FinalConfirm, - ItemsChecked, - TradeComplete, -} - - -#[derive(Debug, Clone)] -pub struct ClientTradeState { - client: ClientId, - other_client: ClientId, - pub items: Vec, - pub meseta: usize, - pub status: TradeStatus, -} - - -impl ClientTradeState { - pub fn client(&self) -> ClientId { - self.client - } - - pub fn other_client(&self) -> ClientId { - self.other_client - } -} - -#[derive(thiserror::Error, Debug)] -pub enum TradeStateError { - #[error("client not in trade {0}")] - ClientNotInTrade(ClientId), - #[error("mismatched trade {0} {1}")] - MismatchedTrade(ClientId, ClientId), -} - -#[derive(Default, Debug, Clone)] -pub struct TradeState { - trades: HashMap>>, -} - -impl TradeState { - pub fn new_trade(&mut self, sender: &ClientId, receiver: &ClientId) { - let state = ClientTradeState { - client: *sender, - other_client: *receiver, - items: Default::default(), - meseta: 0, - status: TradeStatus::SentRequest, - }; - self.trades.insert(*sender, Arc::new(Mutex::new(state))); - - let state = ClientTradeState { - client: *receiver, - other_client: *sender, - items: Default::default(), - meseta: 0, - status: TradeStatus::ReceivedRequest, - }; - self.trades.insert(*receiver, Arc::new(Mutex::new(state))); - } - - pub fn in_trade(&self, client: &ClientId) -> bool { - self.trades.contains_key(client) - } - - /* - pub async fn with<'a, T, F, Fut> (&'a self, client: &ClientId, func: F) -> Result - where - F: FnOnce(MutexGuard<'a, ClientTradeState>, MutexGuard<'a, ClientTradeState>) -> Fut + 'a, - Fut: Future - { - let c1 = self.trades.get(client).ok_or(TradeStateError::ClientNotInTrade(*client))?.lock().await; - let c2 = self.trades.get(&c1.other_client).ok_or(TradeStateError::ClientNotInTrade(c1.other_client))?.lock().await; - - // sanity check - if c1.client != c2.other_client { - return Err(TradeStateError::MismatchedTrade(c1.client, c2.client)); - } - Ok(func(c1, c2).await) - } - */ - pub async fn with<'a, T, F, Fut> (&'a self, client: &ClientId, func: F) -> Result - where - T: Send, - //F: for<'b> FnOnce(&'b mut ClientTradeState, &'b mut ClientTradeState) -> BoxFuture<'b, T> + Send + 'a - //F: for<'b> FnOnce(&'b mut ClientTradeState, &'b mut ClientTradeState) -> Fut + Send + 'a, - F: FnOnce(MutexGuard<'a, ClientTradeState>, MutexGuard<'a, ClientTradeState>) -> Fut + 'a, - Fut: Future, - { - let c1 = self.trades - .get(client) - .ok_or(TradeStateError::ClientNotInTrade(*client))? - .lock() - .await; - let c2 = self.trades - .get(&c1.other_client) - .ok_or(TradeStateError::ClientNotInTrade(c1.other_client))? - .lock() - .await; - - if c1.client != c2.other_client { - return Err(TradeStateError::MismatchedTrade(c1.client, c2.client)); - } - - Ok(func(c1, c2).await) - } - - // TODO: is it possible for this to not return Options? - pub async fn remove_trade(&mut self, client: &ClientId) -> (Option, Option) { - let c1 = OptionFuture::from(self.trades.remove(client).map(|c| async move {c.lock().await.clone()} )).await; - let c2 = if let Some(ref state) = c1 { - OptionFuture::from(self.trades.remove(&state.other_client).map(|c| async move {c.lock().await.clone()})).await - } - else { - None - }; - - (c1, c2) - } -} -- 2.36.0 From 7f421fd2c72da10e736750a0df835b88bc0109f9 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 16:18:20 -0700 Subject: [PATCH 34/58] clippy --- client/src/lib.rs | 1 - room/src/lib.rs | 1 - trade/src/lib.rs | 1 - 3 files changed, 3 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index e75ceaa..43c7a0f 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -11,7 +11,6 @@ use entity::account::{UserAccountEntity, UserSettingsEntity}; use entity::character::CharacterEntity; use entity::item; -use items; use maps::area::MapArea; use shops::{WeaponShopItem, ToolShopItem, ArmorShopItem}; diff --git a/room/src/lib.rs b/room/src/lib.rs index 5110d22..897c20f 100644 --- a/room/src/lib.rs +++ b/room/src/lib.rs @@ -13,7 +13,6 @@ use entity::character::SectionID; use entity::room::{RoomEntityId, RoomEntityMode}; use maps::monster::{load_monster_stats_table, MonsterType, MonsterStats}; use maps::area::MapAreaLookup; -use quests; use maps::Holiday; use location::{MAX_ROOMS, RoomId}; diff --git a/trade/src/lib.rs b/trade/src/lib.rs index a6a7b18..319652c 100644 --- a/trade/src/lib.rs +++ b/trade/src/lib.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; use networking::serverstate::ClientId; -use items; use async_std::sync::{Arc, Mutex, MutexGuard}; use futures::future::{Future, OptionFuture}; use items::trade::TradeItem; -- 2.36.0 From dd8b81e69c4648b612662597636664f13b8c5099 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 16:21:35 -0700 Subject: [PATCH 35/58] remove redundant patch.rs --- src/bin/main.rs | 2 +- src/bin/patch.rs | 2 +- src/patch/mod.rs | 434 ++++++++++++++++++++++++++++++++++++++++++++- src/patch/patch.rs | 432 -------------------------------------------- 4 files changed, 434 insertions(+), 436 deletions(-) delete mode 100644 src/patch/patch.rs diff --git a/src/bin/main.rs b/src/bin/main.rs index 18fdfbd..e50db30 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -4,7 +4,7 @@ use log::{info}; use networking::interserver::AuthToken; use elseware::login::login::LoginServerState; use elseware::login::character::CharacterServerState; -use elseware::patch::patch::{PatchServerState, generate_patch_tree, load_config, load_motd}; +use elseware::patch::{PatchServerState, generate_patch_tree, load_config, load_motd}; use elseware::ship::ship::ShipServerStateBuilder; use maps::Holiday; diff --git a/src/bin/patch.rs b/src/bin/patch.rs index fc9eff8..a9fb839 100644 --- a/src/bin/patch.rs +++ b/src/bin/patch.rs @@ -1,4 +1,4 @@ -use elseware::patch::patch::{PatchServerState, generate_patch_tree, load_config_env, load_motd}; +use elseware::patch::{PatchServerState, generate_patch_tree, load_config_env, load_motd}; use log::info; fn main() { diff --git a/src/patch/mod.rs b/src/patch/mod.rs index 323a777..565530d 100644 --- a/src/patch/mod.rs +++ b/src/patch/mod.rs @@ -1,2 +1,432 @@ -#[allow(clippy::module_inception)] -pub mod patch; +use std::collections::{HashMap, HashSet}; +use std::fs; +use std::io; +use std::io::{Read}; +use std::path::{Path, PathBuf}; +use rand::Rng; +use crc::{crc32, Hasher32}; +use libpso::{PacketParseError, PSOPacket}; +use libpso::packet::patch::*; +use libpso::crypto::pc::PSOPCCipher; +use ron::de::from_str; +use serde::Deserialize; + +use networking::mainloop::{NetworkError}; +use networking::serverstate::{RecvServerPacket, SendServerPacket, ServerState, OnConnect, ClientId}; + +#[derive(Debug)] +pub enum PatchError { + NetworkError(NetworkError), + IOError(std::io::Error), +} + +impl From for PatchError { + fn from(err: NetworkError) -> PatchError { + PatchError::NetworkError(err) + } +} + +impl From for PatchError { + fn from(err: std::io::Error) -> PatchError { + PatchError::IOError(err) + } +} + + +#[derive(Debug, Clone)] +pub struct PatchFile { + path: PathBuf, + checksum: u32, + size: u32, +} + +pub enum PatchTreeIterItem { + Directory(PathBuf), + File(PathBuf, u32), + UpDirectory, +} + +#[derive(Debug, Clone)] +pub enum PatchFileTree { + Directory(PathBuf, Vec), + File(PathBuf, u32), // file_id +} + +impl PatchFileTree { + fn iter_dir(tree: &PatchFileTree) -> Vec { + let mut v = Vec::new(); + + match tree { + PatchFileTree::Directory(dir, files) => { + v.push(PatchTreeIterItem::Directory(dir.clone())); + for file in files { + v.append(&mut PatchFileTree::iter_dir(file)); + } + v.push(PatchTreeIterItem::UpDirectory); + }, + PatchFileTree::File(path, id) => { + v.push(PatchTreeIterItem::File(path.clone(), *id)); + } + } + + v + } + + pub fn flatten(&self) -> Vec { + PatchFileTree::iter_dir(self) + } +} + + +#[derive(Debug)] +pub enum RecvPatchPacket { + PatchWelcomeReply(PatchWelcomeReply), + LoginReply(LoginReply), + FileInfoReply(FileInfoReply), + FileInfoListEnd(FileInfoListEnd), +} + +impl RecvServerPacket for RecvPatchPacket { + fn from_bytes(data: &[u8]) -> Result { + match data[2] { + 0x02 => Ok(RecvPatchPacket::PatchWelcomeReply(PatchWelcomeReply::from_bytes(data)?)), + 0x04 => Ok(RecvPatchPacket::LoginReply(LoginReply::from_bytes(data)?)), + 0x0F => Ok(RecvPatchPacket::FileInfoReply(FileInfoReply::from_bytes(data)?)), + 0x10 => Ok(RecvPatchPacket::FileInfoListEnd(FileInfoListEnd::from_bytes(data)?)), + _ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec())) + } + } +} + +#[derive(Debug)] +pub enum SendPatchPacket { + ChangeDirectory(ChangeDirectory), + EndFileSend(EndFileSend), + FileInfo(FileInfo), + FileSend(Box), + FilesToPatchMetadata(FilesToPatchMetadata), + FinalizePatching(FinalizePatching), + Message(Message), + PatchEndList(PatchEndList), + PatchStartList(PatchStartList), + PatchWelcome(PatchWelcome), + RequestLogin(RequestLogin), + StartFileSend(StartFileSend), + UpOneDirectory(UpOneDirectory), +} + +impl SendServerPacket for SendPatchPacket { + fn as_bytes(&self) -> Vec { + match self { + SendPatchPacket::ChangeDirectory(pkt) => pkt.as_bytes(), + SendPatchPacket::EndFileSend(pkt) => pkt.as_bytes(), + SendPatchPacket::FileInfo(pkt) => pkt.as_bytes(), + SendPatchPacket::FileSend(pkt) => pkt.as_bytes(), + SendPatchPacket::FilesToPatchMetadata(pkt) => pkt.as_bytes(), + SendPatchPacket::FinalizePatching(pkt) => pkt.as_bytes(), + SendPatchPacket::Message(pkt) => pkt.as_bytes(), + SendPatchPacket::PatchEndList(pkt) => pkt.as_bytes(), + SendPatchPacket::PatchStartList(pkt) => pkt.as_bytes(), + SendPatchPacket::PatchWelcome(pkt) => pkt.as_bytes(), + SendPatchPacket::RequestLogin(pkt) => pkt.as_bytes(), + SendPatchPacket::StartFileSend(pkt) => pkt.as_bytes(), + SendPatchPacket::UpOneDirectory(pkt) => pkt.as_bytes(), + } + } +} + + +#[derive(Clone)] +pub struct PatchServerState { + patch_file_tree: PatchFileTree, + patch_file_lookup: HashMap, + patch_file_info: Vec, + patch_motd: String, +} + +impl PatchServerState { + pub fn new(patch_file_tree: PatchFileTree, patch_file_lookup: HashMap, patch_motd: String) -> PatchServerState { + PatchServerState { + patch_file_tree, + patch_file_lookup, + patch_file_info: Vec::new(), + patch_motd, + } + } +} + +#[async_trait::async_trait] +impl ServerState for PatchServerState { + type SendPacket = SendPatchPacket; + type RecvPacket = RecvPatchPacket; + type Cipher = PSOPCCipher; + type PacketError = PatchError; + + async fn on_connect(&mut self, _id: ClientId) -> Result>, PatchError> { + let mut rng = rand::thread_rng(); + let key_in: u32 = rng.gen(); + let key_out: u32 = rng.gen(); + + Ok(vec![OnConnect::Packet(SendPatchPacket::PatchWelcome(PatchWelcome::new(key_out, key_in))), + OnConnect::Cipher(PSOPCCipher::new(key_in), PSOPCCipher::new(key_out)) + ]) + } + + async fn handle(&mut self, id: ClientId, pkt: RecvPatchPacket) -> Result, PatchError> { + Ok(match pkt { + RecvPatchPacket::PatchWelcomeReply(_pkt) => { + vec![SendPatchPacket::RequestLogin(RequestLogin {})] + .into_iter() + .map(move |pkt| (id, pkt)) + .collect() + }, + RecvPatchPacket::LoginReply(_pkt) => { + let mut pkts = vec![SendPatchPacket::Message(Message::new(self.patch_motd.clone()))]; + pkts.append(&mut get_file_list_packets(&self.patch_file_tree)); + pkts.push(SendPatchPacket::PatchEndList(PatchEndList {})); + pkts + .into_iter() + .map(move |pkt| (id, pkt)) + .collect() + }, + RecvPatchPacket::FileInfoReply(pkt) => { + self.patch_file_info.push(pkt); + Vec::new() + }, + RecvPatchPacket::FileInfoListEnd(_pkt) => { + let need_update = self.patch_file_info.iter() + .filter(|file_info| does_file_need_updating(file_info, &self.patch_file_lookup)) + .collect::>(); + + let total_size = need_update.iter().fold(0, |a, file_info| a + file_info.size); + let total_files = need_update.len() as u32; + + vec![SendPatchPacket::FilesToPatchMetadata(FilesToPatchMetadata::new(total_size, total_files)), + SendPatchPacket::PatchStartList(PatchStartList {})] + .into_iter() + .chain(SendFileIterator::new(self)) + .map(move |pkt| (id, pkt)) + .collect() + } + }) + } + + async fn on_disconnect(&mut self, _id: ClientId) -> Result, PatchError> { + Ok(Vec::new()) + } +} + +fn load_patch_dir(basedir: &str, patchbase: &str, file_ids: &mut HashMap) -> PatchFileTree { + let paths = fs::read_dir(basedir).expect("could not read directory"); + + let mut files = Vec::new(); + let mut dirs = Vec::new(); + for p in paths { + let path = p.expect("not a real path").path(); + let patch_path = path.strip_prefix(basedir).unwrap(); + if path.is_dir() { + dirs.push(load_patch_dir(path.to_str().unwrap(), patch_path.to_str().unwrap(), file_ids)); + } + else { + files.push(PatchFileTree::File(patch_path.to_path_buf(), file_ids.len() as u32)); + let (checksum, size) = get_checksum_and_size(&path).unwrap(); + file_ids.insert(file_ids.len() as u32, PatchFile { + path, + checksum, + size, + }); + } + } + + files.append(&mut dirs); + + PatchFileTree::Directory(PathBuf::from(patchbase), files) +} + +pub fn generate_patch_tree(basedir: &str) -> (PatchFileTree, HashMap) { + let mut file_ids = HashMap::new(); + + let patch_tree = load_patch_dir(basedir, "", &mut file_ids); + + (patch_tree, file_ids) +} + + +fn get_file_list_packets(patch_file_tree: &PatchFileTree) -> Vec { + let mut pkts = Vec::new(); + + for item in patch_file_tree.flatten() { + match item { + PatchTreeIterItem::Directory(path) => { + pkts.push(SendPatchPacket::ChangeDirectory(ChangeDirectory::new(path.to_str().unwrap()))); + }, + PatchTreeIterItem::File(path, id) => { + pkts.push(SendPatchPacket::FileInfo(FileInfo::new(path.to_str().unwrap(), id))); + }, + PatchTreeIterItem::UpDirectory => { + pkts.push(SendPatchPacket::UpOneDirectory(UpOneDirectory {})); + } + } + } + + pkts +} + +fn get_checksum_and_size(path: &Path) -> Result<(u32, u32), PatchError> { + let file = fs::File::open(path)?; + let size = file.metadata().unwrap().len(); + let mut crc = crc32::Digest::new(crc32::IEEE); + let mut buf = [0u8; 1024 * 32]; + let mut reader = io::BufReader::new(file); + while let Ok(len) = reader.read(&mut buf) { + if len == 0 { + break; + } + crc.write(&buf[0..len]); + } + + Ok((crc.sum32(), size as u32)) +} + +fn does_file_need_updating(file_info: &FileInfoReply, patch_file_lookup: &HashMap) -> bool { + let patch_file = patch_file_lookup.get(&file_info.id).unwrap(); + patch_file.checksum != file_info.checksum || patch_file.size != file_info.size +} + + +struct SendFileIterator { + done: bool, + file_iter: Box + Send>, + patch_file_lookup: HashMap, + current_file: Option>, + chunk_num: u32, +} + +impl SendFileIterator { + fn new(state: &PatchServerState) -> SendFileIterator { + let file_ids_to_update = state.patch_file_info.iter() + .filter(|file_info| does_file_need_updating(file_info, &state.patch_file_lookup)) + .map(|k| k.id) + .collect::>(); + + SendFileIterator { + done: false, + patch_file_lookup: state.patch_file_lookup.clone(), + file_iter: Box::new(state.patch_file_tree.flatten().into_iter().filter(move |file| { + match file { + PatchTreeIterItem::File(_path, id) => { + file_ids_to_update.contains(id) + }, + _ => true, + } + })), + current_file: None, + chunk_num: 0, + } + } +} + +impl Iterator for SendFileIterator { + type Item = SendPatchPacket; + + fn next(&mut self) -> Option { + if self.done { + return None; + } + + match self.current_file { + Some(ref mut file) => { + let mut buf = [0u8; PATCH_FILE_CHUNK_SIZE as usize]; + let len = file.read(&mut buf).unwrap(); + if len == 0 { + self.current_file = None; + self.chunk_num = 0; + Some(SendPatchPacket::EndFileSend(EndFileSend::new())) + } + else { + let mut crc = crc32::Digest::new(crc32::IEEE); + crc.write(&buf[0..len]); + let pkt = SendPatchPacket::FileSend(Box::new(FileSend { + chunk_num: self.chunk_num, + checksum: crc.sum32(), + chunk_size: len as u32, + buffer: buf, + })); + self.chunk_num += 1; + Some(pkt) + } + }, + None => { + match self.file_iter.next() { + Some(next_file) => { + match next_file { + PatchTreeIterItem::Directory(path) => { + Some(SendPatchPacket::ChangeDirectory(ChangeDirectory::new(path.to_str().unwrap()))) + }, + PatchTreeIterItem::File(path, id) => { + let patch_file = self.patch_file_lookup.get(&id).unwrap(); + let file = fs::File::open(&patch_file.path).unwrap(); + let size = file.metadata().unwrap().len(); + self.current_file = Some(io::BufReader::new(file)); + Some(SendPatchPacket::StartFileSend(StartFileSend::new(path.to_str().unwrap(), size as u32, id))) + }, + PatchTreeIterItem::UpDirectory => { + Some(SendPatchPacket::UpOneDirectory(UpOneDirectory {})) + }, + } + }, + None => { + self.current_file = None; + self.done = true; + Some(SendPatchPacket::FinalizePatching(FinalizePatching {})) + } + } + } + } + } +} + +#[derive(Debug, Deserialize)] +pub struct PatchConfig { + pub path: String, + pub ip: String, // TODO: this does nothing + pub port: u16, +} + +pub fn load_config() -> PatchConfig { + let ini_file = match fs::File::open(std::path::Path::new("patch.ron")) { + Err(err) => panic!("Failed to open patch.ron config file. \n{err}"), + Ok(ini_file) => ini_file, + }; + + let mut s = String::new(); + if let Err(err) = (&ini_file).read_to_string(&mut s) { + panic!("Failed to read patch.ron config file. \n{err}"); + } + + let config: PatchConfig = match from_str(s.as_str()) { + Ok(config) => config, + Err(err) => panic!("Failed to load values from patch.ron \n{err}"), + }; + config +} + +pub fn load_config_env() -> PatchConfig { + let patch_path = std::env::var("PATCHFILE_DIR").unwrap(); + let patch_port = std::env::var("PATCH_PORT").unwrap().parse().unwrap(); + + PatchConfig { + path: patch_path, + ip: "127.0.0.1".into(), + port: patch_port, + } +} + +pub fn load_motd() -> String { + if let Ok(m) = fs::read_to_string("patch.motd") { + m + } + else { + "Welcome to Elseware!".to_string() + } +} diff --git a/src/patch/patch.rs b/src/patch/patch.rs deleted file mode 100644 index 565530d..0000000 --- a/src/patch/patch.rs +++ /dev/null @@ -1,432 +0,0 @@ -use std::collections::{HashMap, HashSet}; -use std::fs; -use std::io; -use std::io::{Read}; -use std::path::{Path, PathBuf}; -use rand::Rng; -use crc::{crc32, Hasher32}; -use libpso::{PacketParseError, PSOPacket}; -use libpso::packet::patch::*; -use libpso::crypto::pc::PSOPCCipher; -use ron::de::from_str; -use serde::Deserialize; - -use networking::mainloop::{NetworkError}; -use networking::serverstate::{RecvServerPacket, SendServerPacket, ServerState, OnConnect, ClientId}; - -#[derive(Debug)] -pub enum PatchError { - NetworkError(NetworkError), - IOError(std::io::Error), -} - -impl From for PatchError { - fn from(err: NetworkError) -> PatchError { - PatchError::NetworkError(err) - } -} - -impl From for PatchError { - fn from(err: std::io::Error) -> PatchError { - PatchError::IOError(err) - } -} - - -#[derive(Debug, Clone)] -pub struct PatchFile { - path: PathBuf, - checksum: u32, - size: u32, -} - -pub enum PatchTreeIterItem { - Directory(PathBuf), - File(PathBuf, u32), - UpDirectory, -} - -#[derive(Debug, Clone)] -pub enum PatchFileTree { - Directory(PathBuf, Vec), - File(PathBuf, u32), // file_id -} - -impl PatchFileTree { - fn iter_dir(tree: &PatchFileTree) -> Vec { - let mut v = Vec::new(); - - match tree { - PatchFileTree::Directory(dir, files) => { - v.push(PatchTreeIterItem::Directory(dir.clone())); - for file in files { - v.append(&mut PatchFileTree::iter_dir(file)); - } - v.push(PatchTreeIterItem::UpDirectory); - }, - PatchFileTree::File(path, id) => { - v.push(PatchTreeIterItem::File(path.clone(), *id)); - } - } - - v - } - - pub fn flatten(&self) -> Vec { - PatchFileTree::iter_dir(self) - } -} - - -#[derive(Debug)] -pub enum RecvPatchPacket { - PatchWelcomeReply(PatchWelcomeReply), - LoginReply(LoginReply), - FileInfoReply(FileInfoReply), - FileInfoListEnd(FileInfoListEnd), -} - -impl RecvServerPacket for RecvPatchPacket { - fn from_bytes(data: &[u8]) -> Result { - match data[2] { - 0x02 => Ok(RecvPatchPacket::PatchWelcomeReply(PatchWelcomeReply::from_bytes(data)?)), - 0x04 => Ok(RecvPatchPacket::LoginReply(LoginReply::from_bytes(data)?)), - 0x0F => Ok(RecvPatchPacket::FileInfoReply(FileInfoReply::from_bytes(data)?)), - 0x10 => Ok(RecvPatchPacket::FileInfoListEnd(FileInfoListEnd::from_bytes(data)?)), - _ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec())) - } - } -} - -#[derive(Debug)] -pub enum SendPatchPacket { - ChangeDirectory(ChangeDirectory), - EndFileSend(EndFileSend), - FileInfo(FileInfo), - FileSend(Box), - FilesToPatchMetadata(FilesToPatchMetadata), - FinalizePatching(FinalizePatching), - Message(Message), - PatchEndList(PatchEndList), - PatchStartList(PatchStartList), - PatchWelcome(PatchWelcome), - RequestLogin(RequestLogin), - StartFileSend(StartFileSend), - UpOneDirectory(UpOneDirectory), -} - -impl SendServerPacket for SendPatchPacket { - fn as_bytes(&self) -> Vec { - match self { - SendPatchPacket::ChangeDirectory(pkt) => pkt.as_bytes(), - SendPatchPacket::EndFileSend(pkt) => pkt.as_bytes(), - SendPatchPacket::FileInfo(pkt) => pkt.as_bytes(), - SendPatchPacket::FileSend(pkt) => pkt.as_bytes(), - SendPatchPacket::FilesToPatchMetadata(pkt) => pkt.as_bytes(), - SendPatchPacket::FinalizePatching(pkt) => pkt.as_bytes(), - SendPatchPacket::Message(pkt) => pkt.as_bytes(), - SendPatchPacket::PatchEndList(pkt) => pkt.as_bytes(), - SendPatchPacket::PatchStartList(pkt) => pkt.as_bytes(), - SendPatchPacket::PatchWelcome(pkt) => pkt.as_bytes(), - SendPatchPacket::RequestLogin(pkt) => pkt.as_bytes(), - SendPatchPacket::StartFileSend(pkt) => pkt.as_bytes(), - SendPatchPacket::UpOneDirectory(pkt) => pkt.as_bytes(), - } - } -} - - -#[derive(Clone)] -pub struct PatchServerState { - patch_file_tree: PatchFileTree, - patch_file_lookup: HashMap, - patch_file_info: Vec, - patch_motd: String, -} - -impl PatchServerState { - pub fn new(patch_file_tree: PatchFileTree, patch_file_lookup: HashMap, patch_motd: String) -> PatchServerState { - PatchServerState { - patch_file_tree, - patch_file_lookup, - patch_file_info: Vec::new(), - patch_motd, - } - } -} - -#[async_trait::async_trait] -impl ServerState for PatchServerState { - type SendPacket = SendPatchPacket; - type RecvPacket = RecvPatchPacket; - type Cipher = PSOPCCipher; - type PacketError = PatchError; - - async fn on_connect(&mut self, _id: ClientId) -> Result>, PatchError> { - let mut rng = rand::thread_rng(); - let key_in: u32 = rng.gen(); - let key_out: u32 = rng.gen(); - - Ok(vec![OnConnect::Packet(SendPatchPacket::PatchWelcome(PatchWelcome::new(key_out, key_in))), - OnConnect::Cipher(PSOPCCipher::new(key_in), PSOPCCipher::new(key_out)) - ]) - } - - async fn handle(&mut self, id: ClientId, pkt: RecvPatchPacket) -> Result, PatchError> { - Ok(match pkt { - RecvPatchPacket::PatchWelcomeReply(_pkt) => { - vec![SendPatchPacket::RequestLogin(RequestLogin {})] - .into_iter() - .map(move |pkt| (id, pkt)) - .collect() - }, - RecvPatchPacket::LoginReply(_pkt) => { - let mut pkts = vec![SendPatchPacket::Message(Message::new(self.patch_motd.clone()))]; - pkts.append(&mut get_file_list_packets(&self.patch_file_tree)); - pkts.push(SendPatchPacket::PatchEndList(PatchEndList {})); - pkts - .into_iter() - .map(move |pkt| (id, pkt)) - .collect() - }, - RecvPatchPacket::FileInfoReply(pkt) => { - self.patch_file_info.push(pkt); - Vec::new() - }, - RecvPatchPacket::FileInfoListEnd(_pkt) => { - let need_update = self.patch_file_info.iter() - .filter(|file_info| does_file_need_updating(file_info, &self.patch_file_lookup)) - .collect::>(); - - let total_size = need_update.iter().fold(0, |a, file_info| a + file_info.size); - let total_files = need_update.len() as u32; - - vec![SendPatchPacket::FilesToPatchMetadata(FilesToPatchMetadata::new(total_size, total_files)), - SendPatchPacket::PatchStartList(PatchStartList {})] - .into_iter() - .chain(SendFileIterator::new(self)) - .map(move |pkt| (id, pkt)) - .collect() - } - }) - } - - async fn on_disconnect(&mut self, _id: ClientId) -> Result, PatchError> { - Ok(Vec::new()) - } -} - -fn load_patch_dir(basedir: &str, patchbase: &str, file_ids: &mut HashMap) -> PatchFileTree { - let paths = fs::read_dir(basedir).expect("could not read directory"); - - let mut files = Vec::new(); - let mut dirs = Vec::new(); - for p in paths { - let path = p.expect("not a real path").path(); - let patch_path = path.strip_prefix(basedir).unwrap(); - if path.is_dir() { - dirs.push(load_patch_dir(path.to_str().unwrap(), patch_path.to_str().unwrap(), file_ids)); - } - else { - files.push(PatchFileTree::File(patch_path.to_path_buf(), file_ids.len() as u32)); - let (checksum, size) = get_checksum_and_size(&path).unwrap(); - file_ids.insert(file_ids.len() as u32, PatchFile { - path, - checksum, - size, - }); - } - } - - files.append(&mut dirs); - - PatchFileTree::Directory(PathBuf::from(patchbase), files) -} - -pub fn generate_patch_tree(basedir: &str) -> (PatchFileTree, HashMap) { - let mut file_ids = HashMap::new(); - - let patch_tree = load_patch_dir(basedir, "", &mut file_ids); - - (patch_tree, file_ids) -} - - -fn get_file_list_packets(patch_file_tree: &PatchFileTree) -> Vec { - let mut pkts = Vec::new(); - - for item in patch_file_tree.flatten() { - match item { - PatchTreeIterItem::Directory(path) => { - pkts.push(SendPatchPacket::ChangeDirectory(ChangeDirectory::new(path.to_str().unwrap()))); - }, - PatchTreeIterItem::File(path, id) => { - pkts.push(SendPatchPacket::FileInfo(FileInfo::new(path.to_str().unwrap(), id))); - }, - PatchTreeIterItem::UpDirectory => { - pkts.push(SendPatchPacket::UpOneDirectory(UpOneDirectory {})); - } - } - } - - pkts -} - -fn get_checksum_and_size(path: &Path) -> Result<(u32, u32), PatchError> { - let file = fs::File::open(path)?; - let size = file.metadata().unwrap().len(); - let mut crc = crc32::Digest::new(crc32::IEEE); - let mut buf = [0u8; 1024 * 32]; - let mut reader = io::BufReader::new(file); - while let Ok(len) = reader.read(&mut buf) { - if len == 0 { - break; - } - crc.write(&buf[0..len]); - } - - Ok((crc.sum32(), size as u32)) -} - -fn does_file_need_updating(file_info: &FileInfoReply, patch_file_lookup: &HashMap) -> bool { - let patch_file = patch_file_lookup.get(&file_info.id).unwrap(); - patch_file.checksum != file_info.checksum || patch_file.size != file_info.size -} - - -struct SendFileIterator { - done: bool, - file_iter: Box + Send>, - patch_file_lookup: HashMap, - current_file: Option>, - chunk_num: u32, -} - -impl SendFileIterator { - fn new(state: &PatchServerState) -> SendFileIterator { - let file_ids_to_update = state.patch_file_info.iter() - .filter(|file_info| does_file_need_updating(file_info, &state.patch_file_lookup)) - .map(|k| k.id) - .collect::>(); - - SendFileIterator { - done: false, - patch_file_lookup: state.patch_file_lookup.clone(), - file_iter: Box::new(state.patch_file_tree.flatten().into_iter().filter(move |file| { - match file { - PatchTreeIterItem::File(_path, id) => { - file_ids_to_update.contains(id) - }, - _ => true, - } - })), - current_file: None, - chunk_num: 0, - } - } -} - -impl Iterator for SendFileIterator { - type Item = SendPatchPacket; - - fn next(&mut self) -> Option { - if self.done { - return None; - } - - match self.current_file { - Some(ref mut file) => { - let mut buf = [0u8; PATCH_FILE_CHUNK_SIZE as usize]; - let len = file.read(&mut buf).unwrap(); - if len == 0 { - self.current_file = None; - self.chunk_num = 0; - Some(SendPatchPacket::EndFileSend(EndFileSend::new())) - } - else { - let mut crc = crc32::Digest::new(crc32::IEEE); - crc.write(&buf[0..len]); - let pkt = SendPatchPacket::FileSend(Box::new(FileSend { - chunk_num: self.chunk_num, - checksum: crc.sum32(), - chunk_size: len as u32, - buffer: buf, - })); - self.chunk_num += 1; - Some(pkt) - } - }, - None => { - match self.file_iter.next() { - Some(next_file) => { - match next_file { - PatchTreeIterItem::Directory(path) => { - Some(SendPatchPacket::ChangeDirectory(ChangeDirectory::new(path.to_str().unwrap()))) - }, - PatchTreeIterItem::File(path, id) => { - let patch_file = self.patch_file_lookup.get(&id).unwrap(); - let file = fs::File::open(&patch_file.path).unwrap(); - let size = file.metadata().unwrap().len(); - self.current_file = Some(io::BufReader::new(file)); - Some(SendPatchPacket::StartFileSend(StartFileSend::new(path.to_str().unwrap(), size as u32, id))) - }, - PatchTreeIterItem::UpDirectory => { - Some(SendPatchPacket::UpOneDirectory(UpOneDirectory {})) - }, - } - }, - None => { - self.current_file = None; - self.done = true; - Some(SendPatchPacket::FinalizePatching(FinalizePatching {})) - } - } - } - } - } -} - -#[derive(Debug, Deserialize)] -pub struct PatchConfig { - pub path: String, - pub ip: String, // TODO: this does nothing - pub port: u16, -} - -pub fn load_config() -> PatchConfig { - let ini_file = match fs::File::open(std::path::Path::new("patch.ron")) { - Err(err) => panic!("Failed to open patch.ron config file. \n{err}"), - Ok(ini_file) => ini_file, - }; - - let mut s = String::new(); - if let Err(err) = (&ini_file).read_to_string(&mut s) { - panic!("Failed to read patch.ron config file. \n{err}"); - } - - let config: PatchConfig = match from_str(s.as_str()) { - Ok(config) => config, - Err(err) => panic!("Failed to load values from patch.ron \n{err}"), - }; - config -} - -pub fn load_config_env() -> PatchConfig { - let patch_path = std::env::var("PATCHFILE_DIR").unwrap(); - let patch_port = std::env::var("PATCH_PORT").unwrap().parse().unwrap(); - - PatchConfig { - path: patch_path, - ip: "127.0.0.1".into(), - port: patch_port, - } -} - -pub fn load_motd() -> String { - if let Ok(m) = fs::read_to_string("patch.motd") { - m - } - else { - "Welcome to Elseware!".to_string() - } -} -- 2.36.0 From a07d7aec231f8a5475060beae902b744885ca146 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 17:11:55 -0700 Subject: [PATCH 36/58] speed up tests by not loading quests every time --- room/src/lib.rs | 13 ++++++---- src/bin/main.rs | 6 +++++ src/bin/ship.rs | 2 ++ src/ship/packet/handler/room.rs | 5 +++- src/ship/ship.rs | 42 ++++++++++++++++++++++++++------- tests/test_rooms.rs | 4 ++++ 6 files changed, 57 insertions(+), 15 deletions(-) diff --git a/room/src/lib.rs b/room/src/lib.rs index 897c20f..3f19b0b 100644 --- a/room/src/lib.rs +++ b/room/src/lib.rs @@ -7,6 +7,7 @@ use futures::stream::{FuturesOrdered, Stream}; use thiserror::Error; use rand::Rng; +use quests::{QuestList, QuestLoadError}; use maps::maps::Maps; use drops::DropTable; use entity::character::SectionID; @@ -177,8 +178,8 @@ pub struct RoomState { pub monster_stats: Box>, pub map_areas: MapAreaLookup, pub quest_group: QuestCategoryType, - pub standard_quests: quests::QuestList, - pub government_quests: quests::QuestList, + pub standard_quests: QuestList, + pub government_quests: QuestList, // enemy info } @@ -213,7 +214,7 @@ impl RoomState { difficulty + 0x22 } - pub fn quests(&self) -> &quests::QuestList { + pub fn quests(&self) -> &QuestList { match self.quest_group { QuestCategoryType::Standard => &self.standard_quests, QuestCategoryType::Government => &self.government_quests, @@ -231,6 +232,8 @@ impl RoomState { event: Holiday, map_builder: Arc Maps + Send + Sync>>, drop_table_builder: Arc DropTable + Send + Sync>>, + standard_quest_builder: Arc Result + Send + Sync>>, + government_quest_builder: Arc Result + Send + Sync>>, ) -> Result { let mode = match mode { RoomEntityMode::Single => RoomMode::Single { @@ -263,8 +266,8 @@ impl RoomState { bursting: false, map_areas: MapAreaLookup::new(&episode), quest_group: QuestCategoryType::Standard, - standard_quests: quests::load_standard_quests(mode)?, - government_quests: quests::load_government_quests(mode)?, + standard_quests: standard_quest_builder(mode)?, + government_quests: government_quest_builder(mode)?, }) } diff --git a/src/bin/main.rs b/src/bin/main.rs index e50db30..a4f0eb0 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -365,6 +365,8 @@ fn main() { .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT) .event(Holiday::Halloween) + .standard_quest_builder(Box::new(quests::load_standard_quests)) + .government_quest_builder(Box::new(quests::load_government_quests)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); @@ -381,6 +383,8 @@ fn main() { .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT+2000) .event(Holiday::Christmas) + .standard_quest_builder(Box::new(quests::load_standard_quests)) + .government_quest_builder(Box::new(quests::load_government_quests)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); @@ -396,6 +400,8 @@ fn main() { .name("JP/Thalarion".into()) .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT+3000) + .standard_quest_builder(Box::new(quests::load_standard_quests)) + .government_quest_builder(Box::new(quests::load_government_quests)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); diff --git a/src/bin/ship.rs b/src/bin/ship.rs index c021601..f6122f7 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -43,6 +43,8 @@ fn main() { .port(elseware::ship::ship::SHIP_PORT) .gateway(entity_gateway) .auth_token(AuthToken(shipgate_token)) + .standard_quest_builder(Box::new(quests::load_standard_quests)) + .government_quest_builder(Box::new(quests::load_government_quests)) .build(); let shipgate_ip = std::env::var("SHIPGATE_IP").unwrap().parse().unwrap(); diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 26e98b4..8ec8e3a 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -20,6 +20,7 @@ use maps::maps::Maps; use location::{ClientLocation, RoomId, RoomLobby, GetAreaError}; use pktbuilder as builder; use items::state::ItemState; +use quests::{QuestList, QuestLoadError}; #[allow(clippy::too_many_arguments)] pub async fn create_room(id: ClientId, @@ -31,6 +32,8 @@ pub async fn create_room(id: ClientId, rooms: &Rooms, map_builder: Arc Maps + Send + Sync>>, drop_table_builder: Arc DropTable + Send + Sync>>, + standard_quest_builder: Arc Result + Send + Sync>>, + government_quest_builder: Arc Result + Send + Sync>>, event: Holiday) -> Result, anyhow::Error> where @@ -91,7 +94,7 @@ where let mut room = RoomState::new(room_entity.id, mode, episode, difficulty, client.character.section_id, name, create_room.password, event, - map_builder, drop_table_builder)?; + map_builder, drop_table_builder, standard_quest_builder, government_quest_builder)?; room.bursting = true; Ok::<_, anyhow::Error>(room) })}).await??; diff --git a/src/ship/ship.rs b/src/ship/ship.rs index e4764e0..edc9a5f 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -25,6 +25,9 @@ use location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; use drops::DropTable; use items; use room; +use maps::room::{RoomMode, Episode, Difficulty}; +//use quests::{load_standard_quests, load_government_quests}; +use quests::{QuestList, QuestLoadError}; use maps::Holiday; use maps::area::MapAreaError; use maps::maps::{Maps, MapsError, generate_free_roam_maps}; @@ -295,14 +298,14 @@ impl SendServerPacket for SendShipPacket { #[derive(Clone)] pub struct ItemShops { - pub weapon_shop: HashMap<(maps::room::Difficulty, SectionID), Arc>>>, + pub weapon_shop: HashMap<(Difficulty, SectionID), Arc>>>, pub tool_shop: Arc>>, pub armor_shop: Arc>>, } impl Default for ItemShops { fn default() -> ItemShops { - let difficulty = [maps::room::Difficulty::Normal, maps::room::Difficulty::Hard, maps::room::Difficulty::VeryHard, maps::room::Difficulty::Ultimate]; + let difficulty = [Difficulty::Normal, Difficulty::Hard, Difficulty::VeryHard, Difficulty::Ultimate]; let section_id = [SectionID::Viridia, SectionID::Greenill, SectionID::Skyly, SectionID::Bluefull, SectionID::Purplenum, SectionID::Pinkal, SectionID::Redria, SectionID::Oran, SectionID::Yellowboze, SectionID::Whitill]; @@ -329,8 +332,10 @@ pub struct ShipServerStateBuilder { port: Option, auth_token: Option, event: Option, - map_builder: Option Maps + Send + Sync>>, - drop_table_builder: Option DropTable + Send + Sync>>, + map_builder: Option Maps + Send + Sync>>, + drop_table_builder: Option DropTable + Send + Sync>>, + standard_quest_builder: Option Result + Send + Sync>>, + government_quest_builder: Option Result + Send + Sync>>, num_blocks: usize, } @@ -345,6 +350,8 @@ impl Default for ShipServerStateBuilder event: None, map_builder: None, drop_table_builder: None, + standard_quest_builder: None, + government_quest_builder: None, num_blocks: 2, } } @@ -388,17 +395,29 @@ impl ShipServerStateBuilder { } #[must_use] - pub fn map_builder(mut self, map_builder: Box Maps + Send + Sync>) -> ShipServerStateBuilder { + pub fn map_builder(mut self, map_builder: Box Maps + Send + Sync>) -> ShipServerStateBuilder { self.map_builder = Some(map_builder); self } #[must_use] - pub fn drop_table_builder(mut self, drop_table_builder: Box DropTable + Send + Sync>) -> ShipServerStateBuilder { + pub fn drop_table_builder(mut self, drop_table_builder: Box DropTable + Send + Sync>) -> ShipServerStateBuilder { self.drop_table_builder = Some(drop_table_builder); self } + #[must_use] + pub fn standard_quest_builder(mut self, standard_quest_builder: Box Result + Send + Sync>) -> ShipServerStateBuilder { + self.standard_quest_builder = Some(standard_quest_builder); + self + } + + #[must_use] + pub fn government_quest_builder(mut self, government_quest_builder: Box Result + Send + Sync>) -> ShipServerStateBuilder { + self.government_quest_builder = Some(government_quest_builder); + self + } + #[must_use] pub fn blocks(mut self, num_blocks: usize) -> ShipServerStateBuilder { self.num_blocks = num_blocks; @@ -419,6 +438,8 @@ impl ShipServerStateBuilder { event: self.event.unwrap_or(Holiday::None), map_builder: Arc::new(self.map_builder.unwrap_or(Box::new(generate_free_roam_maps))), drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or(Box::new(DropTable::new))), + standard_quest_builder: Arc::new(self.standard_quest_builder.unwrap_or(Box::new(|_| Ok(QuestList::new())))), + government_quest_builder: Arc::new(self.government_quest_builder.unwrap_or(Box::new(|_| Ok(QuestList::new())))), auth_token: self.auth_token.unwrap_or_else(|| AuthToken("".into())), ship_list: Arc::new(RwLock::new(Vec::new())), @@ -466,8 +487,10 @@ pub struct ShipServerState { ship_list: Arc>>, shipgate_sender: Option>, trades: TradeState, - map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, + map_builder: Arc Maps + Send + Sync>>, + drop_table_builder: Arc DropTable + Send + Sync>>, + standard_quest_builder: Arc Result + Send + Sync>>, + government_quest_builder: Arc Result + Send + Sync>>, } impl ShipServerState { @@ -709,7 +732,8 @@ impl ServerState for ShipServerState { RecvShipPacket::CreateRoom(create_room) => { let block = self.blocks.get_from_client(id, &self.clients).await?; handler::room::create_room(id, create_room, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, - &block.rooms, self.map_builder.clone(), self.drop_table_builder.clone(), self.event).await? + &block.rooms, self.map_builder.clone(), self.drop_table_builder.clone(), + self.standard_quest_builder.clone(), self.government_quest_builder.clone(), self.event).await? }, RecvShipPacket::RoomNameRequest(_req) => { let block = self.blocks.get_from_client(id, &self.clients).await?; diff --git a/tests/test_rooms.rs b/tests/test_rooms.rs index cb10dfb..4a4f300 100644 --- a/tests/test_rooms.rs +++ b/tests/test_rooms.rs @@ -16,6 +16,8 @@ async fn test_set_valid_quest_group() { let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) + .standard_quest_builder(Box::new(quests::load_standard_quests)) + .government_quest_builder(Box::new(quests::load_government_quests)) .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -36,6 +38,8 @@ async fn test_set_invalid_quest_group() { let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) + .standard_quest_builder(Box::new(quests::load_standard_quests)) + .government_quest_builder(Box::new(quests::load_government_quests)) .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; -- 2.36.0 From b770cce30b4a810b962f31301db68fd01b3a5c57 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 18:17:18 -0700 Subject: [PATCH 37/58] further speed up tests by not loading drop charts by default --- drops/src/lib.rs | 47 ++++++++++++++++++++++++--------- room/src/lib.rs | 6 ++--- src/bin/main.rs | 4 +++ src/bin/ship.rs | 2 ++ src/ship/packet/handler/room.rs | 2 +- src/ship/ship.rs | 10 +++---- tests/test_item_drop.rs | 8 +++--- 7 files changed, 53 insertions(+), 26 deletions(-) diff --git a/drops/src/lib.rs b/drops/src/lib.rs index bccffd4..c7c76d0 100644 --- a/drops/src/lib.rs +++ b/drops/src/lib.rs @@ -98,7 +98,7 @@ impl ItemDropType { .or_else(|_| mag::MagType::parse_type([data[0],data[1],data[2]]).map(ItemType::Mag)) .or_else(|_| tool::ToolType::parse_type([data[0],data[1],data[2]]).map(ItemType::Tool)) .or_else(|_| esweapon::ESWeaponType::parse_type([data[0],data[1],data[2]]).map(ItemType::ESWeapon)).ok()?; - + match item_type { ItemType::Weapon(_w) => Some(ItemDropType::Weapon(weapon::Weapon::from_bytes(data).ok()?)), ItemType::Armor(_a) => Some(ItemDropType::Armor(armor::Armor::from_bytes(data).ok()?)), @@ -121,7 +121,12 @@ pub struct ItemDrop { } -pub struct DropTable { +pub trait DropTable { + fn get_drop(&mut self, map_area: &MapArea, monster: &MonsterType) -> Option; + fn get_box_drop(&mut self, map_area: &MapArea, object: &MapObject) -> Option; +} + +pub struct StandardDropTable { monster_stats: HashMap, rare_table: RareDropTable, weapon_table: GenericWeaponTable, @@ -133,11 +138,11 @@ pub struct DropTable { rng: rand_chacha::ChaCha20Rng, } -impl DropTable { - pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> DropTable { +impl StandardDropTable { + pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> Box { let monster_stats: HashMap = load_data_file(episode, difficulty, section_id, "monster_dar.toml"); - - DropTable { + + Box::new(StandardDropTable { monster_stats: monster_stats.into_iter().map(|(m, s)| (m.parse().unwrap(), s)).collect(), rare_table: RareDropTable::new(episode, difficulty, section_id), weapon_table: GenericWeaponTable::new(episode, difficulty, section_id), @@ -147,7 +152,7 @@ impl DropTable { tool_table: ToolTable::new(episode, difficulty, section_id), box_table: BoxDropTable::new(episode, difficulty, section_id), rng: rand_chacha::ChaCha20Rng::from_entropy(), - } + }) } pub fn builder() -> DropTableBuilder { @@ -177,8 +182,10 @@ impl DropTable { MonsterDropType::None => None, } } +} - pub fn get_drop(&mut self, map_area: &MapArea, monster: &MonsterType) -> Option { +impl DropTable for StandardDropTable { + fn get_drop(&mut self, map_area: &MapArea, monster: &MonsterType) -> Option { let monster_stat = *self.monster_stats.get(monster)?; let drop_anything = self.rng.gen_range(0, 100); @@ -191,7 +198,7 @@ impl DropTable { } let drop_type = self.rng.gen_range(0, 3); - + match drop_type { 0 => { self.generate_meseta(&monster_stat) @@ -206,7 +213,7 @@ impl DropTable { } } - pub fn get_box_drop(&mut self, map_area: &MapArea, object: &MapObject) -> Option { + fn get_box_drop(&mut self, map_area: &MapArea, object: &MapObject) -> Option { self.box_table.get_drop(map_area, object, &mut self.rng) } } @@ -253,8 +260,8 @@ impl DropTableBuilder { self } - pub fn build(self, episode: Episode, difficulty: Difficulty, section_id: SectionID) -> DropTable { - DropTable { + pub fn build(self, episode: Episode, difficulty: Difficulty, section_id: SectionID) -> Box { + Box::new(StandardDropTable { monster_stats: self.monster_stats.unwrap_or_else(|| { let monster_stats: HashMap = load_data_file(episode, difficulty, section_id, "monster_dar.toml"); monster_stats.into_iter().map(|(m, s)| (m.parse().unwrap(), s)).collect() @@ -267,10 +274,24 @@ impl DropTableBuilder { tool_table: self.tool_table.unwrap_or_else(|| ToolTable::new(episode, difficulty, section_id)), box_table: self.box_table.unwrap_or_else(|| BoxDropTable::new(episode, difficulty, section_id)), rng: self.rng.unwrap_or_else(rand_chacha::ChaCha20Rng::from_entropy), - } + }) } } +struct NullDropTable; + +impl DropTable for NullDropTable { + fn get_drop(&mut self, _map_area: &MapArea, _monster: &MonsterType) -> Option { + None + } + fn get_box_drop(&mut self, _map_area: &MapArea, _object: &MapObject) -> Option { + None + } +} + +pub fn null_drop_table(_episode: Episode, _difficult: Difficulty, _section_id: SectionID) -> Box { + Box::new(NullDropTable) +} #[cfg(test)] mod test { diff --git a/room/src/lib.rs b/room/src/lib.rs index 3f19b0b..fca3669 100644 --- a/room/src/lib.rs +++ b/room/src/lib.rs @@ -171,7 +171,7 @@ pub struct RoomState { pub name: String, pub password: [u16; 16], pub maps: Maps, - pub drop_table: Box, + pub drop_table: Box, pub section_id: SectionID, pub random_seed: u32, pub bursting: bool, @@ -231,7 +231,7 @@ impl RoomState { password: [u16; 16], event: Holiday, map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, + drop_table_builder: Arc Box + Send + Sync>>, standard_quest_builder: Arc Result + Send + Sync>>, government_quest_builder: Arc Result + Send + Sync>>, ) -> Result { @@ -262,7 +262,7 @@ impl RoomState { password, maps: map_builder(mode, event), section_id, - drop_table: Box::new(drop_table_builder(episode, difficulty, section_id)), + drop_table: drop_table_builder(episode, difficulty, section_id), bursting: false, map_areas: MapAreaLookup::new(&episode), quest_group: QuestCategoryType::Standard, diff --git a/src/bin/main.rs b/src/bin/main.rs index a4f0eb0..caebcc5 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -13,6 +13,7 @@ use entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; use entity::character::NewCharacterEntity; use entity::item::{NewItemEntity, ItemDetail, InventoryItemEntity}; use entity::item; +use drops::{DropTable, StandardDropTable}; fn setup_logger() { let colors = fern::colors::ColoredLevelConfig::new() @@ -367,6 +368,7 @@ fn main() { .event(Holiday::Halloween) .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) + .drop_table_builder(Box::new(StandardDropTable::new)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); @@ -385,6 +387,7 @@ fn main() { .event(Holiday::Christmas) .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) + .drop_table_builder(Box::new(StandardDropTable::new)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); @@ -402,6 +405,7 @@ fn main() { .port(elseware::ship::ship::SHIP_PORT+3000) .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) + .drop_table_builder(Box::new(StandardDropTable::new)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); diff --git a/src/bin/ship.rs b/src/bin/ship.rs index f6122f7..f5fff5d 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -2,6 +2,7 @@ use log::info; use entity::gateway::postgres::PostgresGateway; use elseware::ship::ship::ShipServerStateBuilder; use networking::interserver::AuthToken; +use drops::{DropTable, StandardDropTable}; fn main() { let colors = fern::colors::ColoredLevelConfig::new() @@ -45,6 +46,7 @@ fn main() { .auth_token(AuthToken(shipgate_token)) .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) + .drop_table_builder(Box::new(StandardDropTable::new)) .build(); let shipgate_ip = std::env::var("SHIPGATE_IP").unwrap().parse().unwrap(); diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 8ec8e3a..563385d 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -31,7 +31,7 @@ pub async fn create_room(id: ClientId, item_state: &mut ItemState, rooms: &Rooms, map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, + drop_table_builder: Arc Box + Send + Sync>>, standard_quest_builder: Arc Result + Send + Sync>>, government_quest_builder: Arc Result + Send + Sync>>, event: Holiday) diff --git a/src/ship/ship.rs b/src/ship/ship.rs index edc9a5f..3ac8225 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -22,7 +22,7 @@ use entity::gateway::{EntityGateway, GatewayError}; use entity::character::SectionID; use entity::room::RoomNote; use location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; -use drops::DropTable; +use drops::{DropTable, null_drop_table}; use items; use room; use maps::room::{RoomMode, Episode, Difficulty}; @@ -333,7 +333,7 @@ pub struct ShipServerStateBuilder { auth_token: Option, event: Option, map_builder: Option Maps + Send + Sync>>, - drop_table_builder: Option DropTable + Send + Sync>>, + drop_table_builder: Option Box + Send + Sync>>, standard_quest_builder: Option Result + Send + Sync>>, government_quest_builder: Option Result + Send + Sync>>, num_blocks: usize, @@ -401,7 +401,7 @@ impl ShipServerStateBuilder { } #[must_use] - pub fn drop_table_builder(mut self, drop_table_builder: Box DropTable + Send + Sync>) -> ShipServerStateBuilder { + pub fn drop_table_builder(mut self, drop_table_builder: Box Box + Send + Sync>) -> ShipServerStateBuilder { self.drop_table_builder = Some(drop_table_builder); self } @@ -437,7 +437,7 @@ impl ShipServerStateBuilder { blocks: Blocks(blocks), event: self.event.unwrap_or(Holiday::None), map_builder: Arc::new(self.map_builder.unwrap_or(Box::new(generate_free_roam_maps))), - drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or(Box::new(DropTable::new))), + drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or(Box::new(null_drop_table))), standard_quest_builder: Arc::new(self.standard_quest_builder.unwrap_or(Box::new(|_| Ok(QuestList::new())))), government_quest_builder: Arc::new(self.government_quest_builder.unwrap_or(Box::new(|_| Ok(QuestList::new())))), @@ -488,7 +488,7 @@ pub struct ShipServerState { shipgate_sender: Option>, trades: TradeState, map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, + drop_table_builder: Arc Box + Send + Sync>>, standard_quest_builder: Arc Result + Send + Sync>>, government_quest_builder: Arc Result + Send + Sync>>, } diff --git a/tests/test_item_drop.rs b/tests/test_item_drop.rs index 20b6a98..029e0ef 100644 --- a/tests/test_item_drop.rs +++ b/tests/test_item_drop.rs @@ -2,7 +2,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::InMemoryGateway; use elseware::ship::ship::{ShipServerState, SendShipPacket, RecvShipPacket}; use maps::monster::MonsterType; -use drops::{DropTable, MonsterDropStats, MonsterDropType}; +use drops::{StandardDropTable, MonsterDropStats, MonsterDropType}; use drops::rare_drop_table::{RareDropTable, RareDropRate, RareDropItem}; use maps::maps::Maps; use maps::area::MapArea; @@ -32,7 +32,7 @@ async fn test_enemy_drops_item() { ) })) .drop_table_builder(Box::new(|episode, difficulty, section_id| { - DropTable::builder() + StandardDropTable::builder() .monster_stat(MonsterType::Hildebear, MonsterDropStats { dar: 100, drop_type: MonsterDropType::Weapon, @@ -88,7 +88,7 @@ async fn test_enemy_drops_item_for_two_players() { ) })) .drop_table_builder(Box::new(|episode, difficulty, section_id| { - DropTable::builder() + StandardDropTable::builder() .monster_stat(MonsterType::Hildebear, MonsterDropStats { dar: 100, drop_type: MonsterDropType::Weapon, @@ -156,7 +156,7 @@ async fn test_enemy_drops_item_for_two_players_and_pick_up() { ) })) .drop_table_builder(Box::new(|episode, difficulty, section_id| { - DropTable::builder() + StandardDropTable::builder() .monster_stat(MonsterType::Hildebear, MonsterDropStats { dar: 100, drop_type: MonsterDropType::Weapon, -- 2.36.0 From 66c04b891e1055908b0e872a6f80e7e4eb5cef95 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 19:05:12 -0700 Subject: [PATCH 38/58] clippy --- drops/src/lib.rs | 1 + src/bin/main.rs | 2 +- src/bin/ship.rs | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drops/src/lib.rs b/drops/src/lib.rs index c7c76d0..1a2cca7 100644 --- a/drops/src/lib.rs +++ b/drops/src/lib.rs @@ -139,6 +139,7 @@ pub struct StandardDropTable { } impl StandardDropTable { + #[allow(clippy::new_ret_no_self)] pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> Box { let monster_stats: HashMap = load_data_file(episode, difficulty, section_id, "monster_dar.toml"); diff --git a/src/bin/main.rs b/src/bin/main.rs index caebcc5..126cbb1 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -13,7 +13,7 @@ use entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; use entity::character::NewCharacterEntity; use entity::item::{NewItemEntity, ItemDetail, InventoryItemEntity}; use entity::item; -use drops::{DropTable, StandardDropTable}; +use drops::StandardDropTable; fn setup_logger() { let colors = fern::colors::ColoredLevelConfig::new() diff --git a/src/bin/ship.rs b/src/bin/ship.rs index f5fff5d..7204925 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -2,7 +2,7 @@ use log::info; use entity::gateway::postgres::PostgresGateway; use elseware::ship::ship::ShipServerStateBuilder; use networking::interserver::AuthToken; -use drops::{DropTable, StandardDropTable}; +use drops::StandardDropTable; fn main() { let colors = fern::colors::ColoredLevelConfig::new() -- 2.36.0 From c5c96863a8e604a6d35ecd76dd16f3cfe7cca057 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 19:58:12 -0700 Subject: [PATCH 39/58] maybe this will work for keeping the ci from filling the disk and making everyone sad --- .drone.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.drone.yml b/.drone.yml index ac685b1..c57acb0 100644 --- a/.drone.yml +++ b/.drone.yml @@ -7,16 +7,40 @@ concurrency: limit: 1 steps: +- name: clean cache + image: rustlang/rust:nightly + volumes: + - name: cache + path: /usr/local/cargo + - name: target-cache + path: /drone/src/target + commands: + - cargo sweep --maxsize 12GiB - name: build image: rustlang/rust:nightly + volumes: + - name: cache + path: /usr/local/cargo + - name: target-cache + path: /drone/src/target commands: - cargo build - name: clippy! image: rustlang/rust:nightly + volumes: + - name: cache + path: /usr/local/cargo + - name: target-cache + path: /drone/src/target commands: - cargo clippy -- --deny warnings - name: test image: rustlang/rust:nightly + volumes: + - name: cache + path: /usr/local/cargo + - name: target-cache + path: /drone/src/target commands: - cargo test --jobs 1 -- 2.36.0 From b5572ccc53608e6ddb86207906bc528798327321 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 21:25:06 -0700 Subject: [PATCH 40/58] null free roam maps by default --- maps/src/maps.rs | 9 +++++++++ src/bin/main.rs | 4 ++++ src/bin/ship.rs | 2 ++ src/ship/ship.rs | 4 ++-- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/maps/src/maps.rs b/maps/src/maps.rs index 4ca76d9..2ed7961 100644 --- a/maps/src/maps.rs +++ b/maps/src/maps.rs @@ -376,3 +376,12 @@ pub fn generate_free_roam_maps(room_mode: RoomMode, event: Holiday) -> Maps { map_variants, } } + + +pub fn null_free_roam_maps(_room_mode: RoomMode, _event: Holiday) -> Maps { + Maps { + enemy_data: Default::default(), + object_data: Default::default(), + map_variants: Default::default(), + } +} diff --git a/src/bin/main.rs b/src/bin/main.rs index 126cbb1..afeb79f 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -8,6 +8,7 @@ use elseware::patch::{PatchServerState, generate_patch_tree, load_config, load_m use elseware::ship::ship::ShipServerStateBuilder; use maps::Holiday; +use maps::maps::generate_free_roam_maps; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; use entity::character::NewCharacterEntity; @@ -369,6 +370,7 @@ fn main() { .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) .drop_table_builder(Box::new(StandardDropTable::new)) + .map_builder(Box::new(generate_free_roam_maps)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); @@ -388,6 +390,7 @@ fn main() { .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) .drop_table_builder(Box::new(StandardDropTable::new)) + .map_builder(Box::new(generate_free_roam_maps)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); @@ -406,6 +409,7 @@ fn main() { .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) .drop_table_builder(Box::new(StandardDropTable::new)) + .map_builder(Box::new(generate_free_roam_maps)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); diff --git a/src/bin/ship.rs b/src/bin/ship.rs index 7204925..b39f504 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -3,6 +3,7 @@ use entity::gateway::postgres::PostgresGateway; use elseware::ship::ship::ShipServerStateBuilder; use networking::interserver::AuthToken; use drops::StandardDropTable; +use maps::maps::generate_free_roam_maps; fn main() { let colors = fern::colors::ColoredLevelConfig::new() @@ -47,6 +48,7 @@ fn main() { .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) .drop_table_builder(Box::new(StandardDropTable::new)) + .map_builder(Box::new(generate_free_roam_maps)) .build(); let shipgate_ip = std::env::var("SHIPGATE_IP").unwrap().parse().unwrap(); diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 3ac8225..23eadcd 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -30,7 +30,7 @@ use maps::room::{RoomMode, Episode, Difficulty}; use quests::{QuestList, QuestLoadError}; use maps::Holiday; use maps::area::MapAreaError; -use maps::maps::{Maps, MapsError, generate_free_roam_maps}; +use maps::maps::{Maps, MapsError, null_free_roam_maps}; use crate::ship::packet::handler; use shops::{WeaponShop, ToolShop, ArmorShop}; use trade::TradeState; @@ -436,7 +436,7 @@ impl ShipServerStateBuilder { shops: ItemShops::default(), blocks: Blocks(blocks), event: self.event.unwrap_or(Holiday::None), - map_builder: Arc::new(self.map_builder.unwrap_or(Box::new(generate_free_roam_maps))), + map_builder: Arc::new(self.map_builder.unwrap_or(Box::new(null_free_roam_maps))), drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or(Box::new(null_drop_table))), standard_quest_builder: Arc::new(self.standard_quest_builder.unwrap_or(Box::new(|_| Ok(QuestList::new())))), government_quest_builder: Arc::new(self.government_quest_builder.unwrap_or(Box::new(|_| Ok(QuestList::new())))), -- 2.36.0 From 9bb10476a33e770be80218ca67f90710af58e232 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 22:02:36 -0700 Subject: [PATCH 41/58] default to useful things, tests null things out on their own --- drops/src/lib.rs | 15 ---- src/bin/main.rs | 12 --- src/bin/ship.rs | 4 - src/ship/ship.rs | 14 ++-- tests/common.rs | 49 +++++++++++- tests/test_bank.rs | 124 ++++++++---------------------- tests/test_character.rs | 8 +- tests/test_exp_gain.rs | 76 +++++++++--------- tests/test_item_actions.rs | 12 +-- tests/test_item_drop.rs | 153 ++++++++++++++++++------------------- tests/test_item_id.rs | 12 +-- tests/test_item_pickup.rs | 44 +++-------- tests/test_item_use.rs | 32 ++------ tests/test_mags.rs | 12 +-- tests/test_rooms.rs | 22 ++---- tests/test_shops.rs | 108 +++++++------------------- tests/test_trade.rs | 152 +++++++++--------------------------- 17 files changed, 297 insertions(+), 552 deletions(-) diff --git a/drops/src/lib.rs b/drops/src/lib.rs index 1a2cca7..32a14db 100644 --- a/drops/src/lib.rs +++ b/drops/src/lib.rs @@ -279,21 +279,6 @@ impl DropTableBuilder { } } -struct NullDropTable; - -impl DropTable for NullDropTable { - fn get_drop(&mut self, _map_area: &MapArea, _monster: &MonsterType) -> Option { - None - } - fn get_box_drop(&mut self, _map_area: &MapArea, _object: &MapObject) -> Option { - None - } -} - -pub fn null_drop_table(_episode: Episode, _difficult: Difficulty, _section_id: SectionID) -> Box { - Box::new(NullDropTable) -} - #[cfg(test)] mod test { use super::*; diff --git a/src/bin/main.rs b/src/bin/main.rs index afeb79f..79f95be 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -367,10 +367,6 @@ fn main() { .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT) .event(Holiday::Halloween) - .standard_quest_builder(Box::new(quests::load_standard_quests)) - .government_quest_builder(Box::new(quests::load_government_quests)) - .drop_table_builder(Box::new(StandardDropTable::new)) - .map_builder(Box::new(generate_free_roam_maps)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); @@ -387,10 +383,6 @@ fn main() { .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT+2000) .event(Holiday::Christmas) - .standard_quest_builder(Box::new(quests::load_standard_quests)) - .government_quest_builder(Box::new(quests::load_government_quests)) - .drop_table_builder(Box::new(StandardDropTable::new)) - .map_builder(Box::new(generate_free_roam_maps)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); @@ -406,10 +398,6 @@ fn main() { .name("JP/Thalarion".into()) .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT+3000) - .standard_quest_builder(Box::new(quests::load_standard_quests)) - .government_quest_builder(Box::new(quests::load_government_quests)) - .drop_table_builder(Box::new(StandardDropTable::new)) - .map_builder(Box::new(generate_free_roam_maps)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); diff --git a/src/bin/ship.rs b/src/bin/ship.rs index b39f504..baf87c6 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -45,10 +45,6 @@ fn main() { .port(elseware::ship::ship::SHIP_PORT) .gateway(entity_gateway) .auth_token(AuthToken(shipgate_token)) - .standard_quest_builder(Box::new(quests::load_standard_quests)) - .government_quest_builder(Box::new(quests::load_government_quests)) - .drop_table_builder(Box::new(StandardDropTable::new)) - .map_builder(Box::new(generate_free_roam_maps)) .build(); let shipgate_ip = std::env::var("SHIPGATE_IP").unwrap().parse().unwrap(); diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 23eadcd..3ee833f 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -22,15 +22,15 @@ use entity::gateway::{EntityGateway, GatewayError}; use entity::character::SectionID; use entity::room::RoomNote; use location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; -use drops::{DropTable, null_drop_table}; +use drops::{DropTable, StandardDropTable}; use items; use room; use maps::room::{RoomMode, Episode, Difficulty}; -//use quests::{load_standard_quests, load_government_quests}; +use quests::{load_standard_quests, load_government_quests}; use quests::{QuestList, QuestLoadError}; use maps::Holiday; use maps::area::MapAreaError; -use maps::maps::{Maps, MapsError, null_free_roam_maps}; +use maps::maps::{Maps, MapsError, generate_free_roam_maps}; use crate::ship::packet::handler; use shops::{WeaponShop, ToolShop, ArmorShop}; use trade::TradeState; @@ -436,10 +436,10 @@ impl ShipServerStateBuilder { shops: ItemShops::default(), blocks: Blocks(blocks), event: self.event.unwrap_or(Holiday::None), - map_builder: Arc::new(self.map_builder.unwrap_or(Box::new(null_free_roam_maps))), - drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or(Box::new(null_drop_table))), - standard_quest_builder: Arc::new(self.standard_quest_builder.unwrap_or(Box::new(|_| Ok(QuestList::new())))), - government_quest_builder: Arc::new(self.government_quest_builder.unwrap_or(Box::new(|_| Ok(QuestList::new())))), + map_builder: Arc::new(self.map_builder.unwrap_or(Box::new(generate_free_roam_maps))), + drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or(Box::new(StandardDropTable::new))), + standard_quest_builder: Arc::new(self.standard_quest_builder.unwrap_or(Box::new(load_standard_quests))), + government_quest_builder: Arc::new(self.government_quest_builder.unwrap_or(Box::new(load_government_quests))), auth_token: self.auth_token.unwrap_or_else(|| AuthToken("".into())), ship_list: Arc::new(RwLock::new(Vec::new())), diff --git a/tests/common.rs b/tests/common.rs index 1c11777..f28d318 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -3,10 +3,16 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::EntityGateway; use entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity}; -use entity::character::{CharacterEntity, NewCharacterEntity}; +use entity::character::{CharacterEntity, NewCharacterEntity, SectionID}; use entity::item::{Meseta, BankIdentifier}; -use elseware::ship::ship::{ShipServerState, RecvShipPacket}; -use maps::room::Difficulty; +use elseware::ship::ship::{ShipServerState, ShipServerStateBuilder, RecvShipPacket}; +use maps::room::{RoomMode, Difficulty, Episode}; +use maps::area::MapArea; +use maps::maps::null_free_roam_maps; +use maps::object::MapObject; +use maps::monster::MonsterType; +use quests::{QuestList, QuestLoadError}; +use drops::{DropTable, ItemDropType}; use entity::item; @@ -14,6 +20,43 @@ use libpso::packet::ship::*; use libpso::packet::login::{Login, Session}; use libpso::{utf8_to_array, utf8_to_utf16_array}; +fn null_quest_builder(_mode: RoomMode) -> Result { + Ok(Default::default()) +} + +struct NullDropTable; + +impl DropTable for NullDropTable { + fn get_drop(&mut self, _map_area: &MapArea, _monster: &MonsterType) -> Option { + None + } + fn get_box_drop(&mut self, _map_area: &MapArea, _object: &MapObject) -> Option { + None + } +} + +pub fn null_drop_table_builder(_episode: Episode, _difficult: Difficulty, _section_id: SectionID) -> Box { + Box::new(NullDropTable) +} + +pub fn standard_ship_buildable(gateway: EG) -> ShipServerStateBuilder { + ShipServerState::builder() + .gateway(gateway) + .standard_quest_builder(Box::new(null_quest_builder)) + .government_quest_builder(Box::new(null_quest_builder)) + .drop_table_builder(Box::new(null_drop_table_builder)) + .map_builder(Box::new(null_free_roam_maps)) +} + +pub fn standard_ship(gateway: EG) -> ShipServerState { + ShipServerState::builder() + .gateway(gateway) + .standard_quest_builder(Box::new(null_quest_builder)) + .government_quest_builder(Box::new(null_quest_builder)) + .drop_table_builder(Box::new(null_drop_table_builder)) + .map_builder(Box::new(null_free_roam_maps)) + .build() +} //TODO: remove kb_conf_preset pub async fn new_user_character(entity_gateway: &mut EG, username: &str, password: &str, kb_conf_preset: usize) -> (UserAccountEntity, CharacterEntity) { diff --git a/tests/test_bank.rs b/tests/test_bank.rs index c7d7f20..2a97d6b 100644 --- a/tests/test_bank.rs +++ b/tests/test_bank.rs @@ -33,9 +33,7 @@ async fn test_bank_items_sent_in_character_login() { entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![item]), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; let packets = ship.handle(ClientId(1), RecvShipPacket::MenuSelect(MenuSelect { @@ -71,9 +69,7 @@ async fn test_request_bank_items() { entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -115,9 +111,7 @@ async fn test_request_stacked_bank_items() { entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -180,9 +174,7 @@ async fn test_request_bank_items_sorted() { let bank = vec![item::BankItemEntity::Individual(item1), vec![monomate].into(), item2.into()]; entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -237,9 +229,7 @@ async fn test_deposit_individual_item() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![item0, item1])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -303,9 +293,7 @@ async fn test_deposit_stacked_item() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -364,9 +352,7 @@ async fn test_deposit_partial_stacked_item() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -445,9 +431,7 @@ async fn test_deposit_stacked_item_with_stack_already_in_bank() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -518,9 +502,7 @@ async fn test_deposit_stacked_item_with_full_stack_in_bank() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -596,9 +578,7 @@ async fn test_deposit_individual_item_in_full_bank() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -668,9 +648,7 @@ async fn test_deposit_stacked_item_in_full_bank() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(full_bank), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -754,9 +732,7 @@ async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(almost_full_bank), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -794,9 +770,7 @@ async fn test_deposit_meseta() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -831,9 +805,7 @@ async fn test_deposit_too_much_meseta() { entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(999980)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -870,9 +842,7 @@ async fn test_deposit_meseta_when_bank_is_maxed() { entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(999999)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -925,9 +895,7 @@ async fn test_withdraw_individual_item() { entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -985,9 +953,7 @@ async fn test_withdraw_stacked_item() { entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -1044,9 +1010,7 @@ async fn test_withdraw_partial_stacked_item() { } entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -1122,9 +1086,7 @@ async fn test_withdraw_stacked_item_with_stack_already_in_inventory() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -1197,9 +1159,7 @@ async fn test_withdraw_stacked_item_with_full_stack_in_inventory() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -1275,9 +1235,7 @@ async fn test_withdraw_individual_item_in_full_inventory() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -1343,9 +1301,7 @@ async fn test_withdraw_stacked_item_in_full_inventory() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -1430,9 +1386,7 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(items)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -1473,9 +1427,7 @@ async fn test_withdraw_meseta() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -1510,9 +1462,7 @@ async fn test_withdraw_too_much_meseta() { entity_gateway.set_character_meseta(&char1.id, item::Meseta(999980)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -1549,9 +1499,7 @@ async fn test_withdraw_meseta_inventory_is_maxed() { entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -1590,9 +1538,7 @@ async fn test_withdraw_meseta_and_buy_a_few_monomates_with_it() { entity_gateway.set_character_meseta(&char1.id, item::Meseta(100)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -1649,9 +1595,7 @@ async fn test_deposit_items_into_shared_banks() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![item0, item1, item2, item3, item4, item5])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -1765,9 +1709,7 @@ async fn test_deposit_meseta_into_shared_banks() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -1852,9 +1794,7 @@ async fn test_withdraw_items_from_shared_banks() { entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![item2, item3]), &item::BankIdentifier::Shared(item::BankName("asdf".into()))).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![item4, item5]), &item::BankIdentifier::Shared(item::BankName("qwer".into()))).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -1956,9 +1896,7 @@ async fn test_withdraw_meseta_from_shared_banks() { entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Shared(item::BankName("asdf".into())), item::Meseta(300)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Shared(item::BankName("qwer".into())), item::Meseta(300)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; diff --git a/tests/test_character.rs b/tests/test_character.rs index 9052c74..ee78434 100644 --- a/tests/test_character.rs +++ b/tests/test_character.rs @@ -15,9 +15,7 @@ async fn test_save_options() { let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -37,9 +35,7 @@ async fn test_change_keyboard_mappings() { let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 2).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; diff --git a/tests/test_exp_gain.rs b/tests/test_exp_gain.rs index 13a0eca..5e4bcf9 100644 --- a/tests/test_exp_gain.rs +++ b/tests/test_exp_gain.rs @@ -21,16 +21,15 @@ async fn test_character_gains_exp() { let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .map_builder(Box::new(|_room_mode, _event| { - Maps::new( - vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], - vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], - Vec::new(), - ) - })) - .build()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .map_builder(Box::new(|_room_mode, _event| { + Maps::new( + vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], + vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], + Vec::new(), + ) + })) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -57,16 +56,15 @@ async fn test_character_levels_up() { char1.exp = 49; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .map_builder(Box::new(|_room_mode, _event| { - Maps::new( - vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], - vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], - Vec::new(), - ) - })) - .build()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .map_builder(Box::new(|_room_mode, _event| { + Maps::new( + vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], + vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], + Vec::new(), + ) + })) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -94,16 +92,15 @@ async fn test_character_levels_up_multiple_times() { let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .map_builder(Box::new(|_room_mode, _event| { - Maps::new( - vec![MapVariant::new(MapArea::DarkFalz, MapVariantMode::Online)], - vec![Some(MapEnemy::new(MonsterType::DarkFalz2, MapArea::DarkFalz))], - Vec::new(), - ) - })) - .build()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .map_builder(Box::new(|_room_mode, _event| { + Maps::new( + vec![MapVariant::new(MapArea::DarkFalz, MapVariantMode::Online)], + vec![Some(MapEnemy::new(MonsterType::DarkFalz2, MapArea::DarkFalz))], + Vec::new(), + ) + })) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -131,16 +128,15 @@ async fn test_one_character_gets_full_exp_and_other_attacker_gets_partial() { let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .map_builder(Box::new(|_room_mode, _event| { - Maps::new( - vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], - vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], - Vec::new(), - ) - })) - .build()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .map_builder(Box::new(|_room_mode, _event| { + Maps::new( + vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], + vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], + Vec::new(), + ) + })) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; diff --git a/tests/test_item_actions.rs b/tests/test_item_actions.rs index 9964bd6..0212d08 100644 --- a/tests/test_item_actions.rs +++ b/tests/test_item_actions.rs @@ -56,9 +56,7 @@ async fn test_equip_unit_from_equip_menu() { entity_gateway.set_character_equips(&char1.id, &equipped).await.unwrap(); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -133,9 +131,7 @@ async fn test_unequip_armor_with_units() { entity_gateway.set_character_equips(&char1.id, &equipped).await.unwrap(); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -193,9 +189,7 @@ async fn test_sort_items() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; diff --git a/tests/test_item_drop.rs b/tests/test_item_drop.rs index 029e0ef..bac45ac 100644 --- a/tests/test_item_drop.rs +++ b/tests/test_item_drop.rs @@ -22,32 +22,31 @@ async fn test_enemy_drops_item() { let mut entity_gateway = InMemoryGateway::default(); let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .map_builder(Box::new(|_room_mode, _event| { - Maps::new( - vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], - vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], - Vec::new(), - ) - })) - .drop_table_builder(Box::new(|episode, difficulty, section_id| { - StandardDropTable::builder() - .monster_stat(MonsterType::Hildebear, MonsterDropStats { - dar: 100, - drop_type: MonsterDropType::Weapon, - min_meseta: 0, - max_meseta: 0, - }) - .rare_table(RareDropTable::builder() - .rate(MonsterType::Hildebear, RareDropRate { - rate: 1.0, - item: RareDropItem::Weapon(WeaponType::DarkFlow) - }) - .build(episode, difficulty, section_id)) - .build(episode, difficulty, section_id) - })) - .build()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .map_builder(Box::new(|_room_mode, _event| { + Maps::new( + vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], + vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], + Vec::new(), + ) + })) + .drop_table_builder(Box::new(|episode, difficulty, section_id| { + StandardDropTable::builder() + .monster_stat(MonsterType::Hildebear, MonsterDropStats { + dar: 100, + drop_type: MonsterDropType::Weapon, + min_meseta: 0, + max_meseta: 0, + }) + .rare_table(RareDropTable::builder() + .rate(MonsterType::Hildebear, RareDropRate { + rate: 1.0, + item: RareDropItem::Weapon(WeaponType::DarkFlow) + }) + .build(episode, difficulty, section_id)) + .build(episode, difficulty, section_id) + })) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -78,32 +77,31 @@ async fn test_enemy_drops_item_for_two_players() { let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .map_builder(Box::new(|_room_mode, _event| { - Maps::new( - vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], - vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], - Vec::new(), - ) - })) - .drop_table_builder(Box::new(|episode, difficulty, section_id| { - StandardDropTable::builder() - .monster_stat(MonsterType::Hildebear, MonsterDropStats { - dar: 100, - drop_type: MonsterDropType::Weapon, - min_meseta: 0, - max_meseta: 0, - }) - .rare_table(RareDropTable::builder() - .rate(MonsterType::Hildebear, RareDropRate { - rate: 1.0, - item: RareDropItem::Weapon(WeaponType::DarkFlow) - }) - .build(episode, difficulty, section_id)) - .build(episode, difficulty, section_id) - })) - .build()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .map_builder(Box::new(|_room_mode, _event| { + Maps::new( + vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], + vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], + Vec::new(), + ) + })) + .drop_table_builder(Box::new(|episode, difficulty, section_id| { + StandardDropTable::builder() + .monster_stat(MonsterType::Hildebear, MonsterDropStats { + dar: 100, + drop_type: MonsterDropType::Weapon, + min_meseta: 0, + max_meseta: 0, + }) + .rare_table(RareDropTable::builder() + .rate(MonsterType::Hildebear, RareDropRate { + rate: 1.0, + item: RareDropItem::Weapon(WeaponType::DarkFlow) + }) + .build(episode, difficulty, section_id)) + .build(episode, difficulty, section_id) + })) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -146,32 +144,31 @@ async fn test_enemy_drops_item_for_two_players_and_pick_up() { let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .map_builder(Box::new(|_room_mode, _event| { - Maps::new( - vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], - vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], - Vec::new(), - ) - })) - .drop_table_builder(Box::new(|episode, difficulty, section_id| { - StandardDropTable::builder() - .monster_stat(MonsterType::Hildebear, MonsterDropStats { - dar: 100, - drop_type: MonsterDropType::Weapon, - min_meseta: 0, - max_meseta: 0, - }) - .rare_table(RareDropTable::builder() - .rate(MonsterType::Hildebear, RareDropRate { - rate: 1.0, - item: RareDropItem::Weapon(WeaponType::DarkFlow) - }) - .build(episode, difficulty, section_id)) - .build(episode, difficulty, section_id) - })) - .build()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .map_builder(Box::new(|_room_mode, _event| { + Maps::new( + vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], + vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], + Vec::new(), + ) + })) + .drop_table_builder(Box::new(|episode, difficulty, section_id| { + StandardDropTable::builder() + .monster_stat(MonsterType::Hildebear, MonsterDropStats { + dar: 100, + drop_type: MonsterDropType::Weapon, + min_meseta: 0, + max_meseta: 0, + }) + .rare_table(RareDropTable::builder() + .rate(MonsterType::Hildebear, RareDropRate { + rate: 1.0, + item: RareDropItem::Weapon(WeaponType::DarkFlow) + }) + .build(episode, difficulty, section_id)) + .build(episode, difficulty, section_id) + })) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; diff --git a/tests/test_item_id.rs b/tests/test_item_id.rs index 06ec3b4..ff8f4ad 100644 --- a/tests/test_item_id.rs +++ b/tests/test_item_id.rs @@ -53,9 +53,7 @@ async fn test_use_monomate_after_leaving_and_rejoining_room() { entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_items)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -167,9 +165,7 @@ async fn test_using_some_monomates_after_a_convoluted_series_of_leaves_and_joins } entity_gateway.set_character_inventory(&char3.id, &item::InventoryEntity::new(p3_items)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; log_in_char(&mut ship, ClientId(3), "a3", "a").await; @@ -330,9 +326,7 @@ async fn test_depositing_a_full_stack_then_withdrawing_part() { } entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; diff --git a/tests/test_item_pickup.rs b/tests/test_item_pickup.rs index fd38cb1..d1ba62e 100644 --- a/tests/test_item_pickup.rs +++ b/tests/test_item_pickup.rs @@ -34,9 +34,7 @@ async fn test_pick_up_individual_item() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -117,9 +115,7 @@ async fn test_pick_up_item_stack_of_items_already_in_inventory() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_monomate])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_items)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -176,9 +172,7 @@ async fn test_pick_up_item_stack_of_items_not_already_held() { entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomate])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -242,9 +236,7 @@ async fn test_pick_up_meseta_when_inventory_full() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); entity_gateway.set_character_meseta(&char2.id, item::Meseta(300)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -334,9 +326,7 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomates])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -412,9 +402,7 @@ async fn test_can_not_pick_up_item_when_inventory_full() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -470,9 +458,7 @@ async fn test_can_not_drop_more_meseta_than_is_held() { entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -535,9 +521,7 @@ async fn test_pick_up_stack_that_would_exceed_stack_limit() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_monomates])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomates])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -586,9 +570,7 @@ async fn test_can_not_pick_up_meseta_when_full() { entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); entity_gateway.set_character_meseta(&char2.id, item::Meseta(300)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -641,9 +623,7 @@ async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() { entity_gateway.set_character_meseta(&char1.id, item::Meseta(999998)).await.unwrap(); entity_gateway.set_character_meseta(&char2.id, item::Meseta(300)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -706,9 +686,7 @@ async fn test_player_drops_partial_stack_and_other_player_picks_it_up() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; diff --git a/tests/test_item_use.rs b/tests/test_item_use.rs index 67a29b2..0f28a18 100644 --- a/tests/test_item_use.rs +++ b/tests/test_item_use.rs @@ -36,9 +36,7 @@ async fn test_use_monomate() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -83,9 +81,7 @@ async fn test_use_monomate_twice() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -131,9 +127,7 @@ async fn test_use_last_monomate() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -171,9 +165,7 @@ async fn test_use_nonstackable_tool() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -212,9 +204,7 @@ async fn test_use_materials() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -277,9 +267,7 @@ async fn test_jackolantern() { ])]; entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -346,9 +334,7 @@ async fn test_use_barta_1() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -417,9 +403,7 @@ async fn test_use_monogrinder() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![item::InventoryItemEntity::Individual(saber), item::InventoryItemEntity::Stacked(grinders)])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; diff --git a/tests/test_mags.rs b/tests/test_mags.rs index 68adbcd..963e71a 100644 --- a/tests/test_mags.rs +++ b/tests/test_mags.rs @@ -50,9 +50,7 @@ async fn test_mag_feed() { inventory.push(item::InventoryItemEntity::Stacked(monomates)); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -105,9 +103,7 @@ async fn test_mag_change_owner() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![mag])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -191,9 +187,7 @@ async fn test_mag_cell() { entity_gateway.set_character_equips(&char1.id, &equipped).await.unwrap(); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![mag, mag_cell])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; diff --git a/tests/test_rooms.rs b/tests/test_rooms.rs index 4a4f300..ced3e27 100644 --- a/tests/test_rooms.rs +++ b/tests/test_rooms.rs @@ -14,11 +14,10 @@ use common::*; async fn test_set_valid_quest_group() { let mut entity_gateway = InMemoryGateway::default(); let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) + let mut ship = standard_ship_buildable(entity_gateway.clone()) .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) - .build()); + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -36,11 +35,10 @@ async fn test_set_valid_quest_group() { async fn test_set_invalid_quest_group() { let mut entity_gateway = InMemoryGateway::default(); let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) + let mut ship = standard_ship_buildable(entity_gateway.clone()) .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) - .build()); + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; @@ -63,9 +61,7 @@ async fn test_get_room_info() { _char1.name = String::from("GODmar"); entity_gateway.save_character(&_char1).await.unwrap(); let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -84,9 +80,7 @@ async fn test_cannot_get_room_info_after_room_is_closed() { let mut entity_gateway = InMemoryGateway::default(); let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -106,9 +100,7 @@ async fn test_cannot_join_room_after_its_closed() { let mut entity_gateway = InMemoryGateway::default(); let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; diff --git a/tests/test_shops.rs b/tests/test_shops.rs index c54d907..392fa5a 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -20,9 +20,7 @@ async fn test_player_opens_weapon_shop() { char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -50,9 +48,7 @@ async fn test_player_opens_tool_shop() { char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -80,9 +76,7 @@ async fn test_player_opens_armor_shop() { char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -111,9 +105,7 @@ async fn test_player_buys_from_weapon_shop() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -149,9 +141,7 @@ async fn test_player_buys_from_tool_shop() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -186,9 +176,7 @@ async fn test_player_buys_multiple_from_tool_shop() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -227,9 +215,7 @@ async fn test_player_buys_from_armor_shop() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -280,9 +266,7 @@ async fn test_player_sells_3_attr_weapon_to_shop() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -309,9 +293,7 @@ async fn test_other_clients_see_purchase() { entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -360,9 +342,7 @@ async fn test_other_clients_see_stacked_purchase() { ), }).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -399,9 +379,7 @@ async fn test_buying_item_without_enough_mseseta() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Normal).await; @@ -437,9 +415,7 @@ async fn test_player_double_buys_from_tool_shop() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -502,9 +478,7 @@ async fn test_techs_disappear_from_shop_when_bought() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -564,9 +538,7 @@ async fn test_units_disappear_from_shop_when_bought() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -641,9 +613,7 @@ async fn test_player_sells_untekked_weapon() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -685,9 +655,7 @@ async fn test_player_sells_rare_item() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -728,9 +696,7 @@ async fn test_player_sells_partial_photon_drop_stack() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -769,9 +735,7 @@ async fn test_player_sells_basic_frame() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -810,9 +774,7 @@ async fn test_player_sells_max_frame() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -850,9 +812,7 @@ async fn test_player_sells_basic_barrier() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -890,9 +850,7 @@ async fn test_player_sells_max_barrier() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -929,9 +887,7 @@ async fn test_player_sells_1_star_minusminus_unit() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -968,9 +924,7 @@ async fn test_player_sells_5_star_plusplus_unit() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -1009,9 +963,7 @@ async fn test_player_sells_rare_frame() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -1049,9 +1001,7 @@ async fn test_player_sells_rare_barrier() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -1088,9 +1038,7 @@ async fn test_player_sells_rare_unit() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -1128,9 +1076,7 @@ async fn test_player_cant_sell_if_meseta_would_go_over_max() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; diff --git a/tests/test_trade.rs b/tests/test_trade.rs index 9799156..ec4fb3c 100644 --- a/tests/test_trade.rs +++ b/tests/test_trade.rs @@ -133,9 +133,7 @@ async fn test_trade_one_individual_item() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -234,9 +232,7 @@ async fn test_trade_player2_to_player1() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -335,9 +331,7 @@ async fn test_reverse_trade_ack_order() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -439,9 +433,7 @@ async fn test_trade_one_stacked_item() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -543,9 +535,7 @@ async fn test_trade_partial_stacked_item() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -660,9 +650,7 @@ async fn test_trade_individual_both() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -832,9 +820,7 @@ async fn test_trade_stacked_both() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_stack])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -1002,9 +988,7 @@ async fn test_trade_partial_stack_both() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_stack])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -1178,9 +1162,7 @@ async fn test_trade_same_stacked_item_to_eachother() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_stack])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -1350,9 +1332,7 @@ async fn test_trade_stacked_when_already_have_partial_stack() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_stack])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -1487,9 +1467,7 @@ async fn test_trade_individual_for_stacked() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_stack])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -1679,9 +1657,7 @@ async fn test_trade_multiple_individual() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -1950,9 +1926,7 @@ async fn test_trade_multiple_stacked() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack1, p1_stack2])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_stack1, p2_stack2])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -2195,9 +2169,7 @@ async fn test_trade_not_enough_inventory_space_individual() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -2313,9 +2285,7 @@ async fn test_trade_not_enough_inventory_space_stacked() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -2425,9 +2395,7 @@ async fn test_trade_stack_too_big() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_stack])).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -2506,9 +2474,7 @@ async fn test_trade_meseta() { entity_gateway.set_character_meseta(&char1.id, Meseta(2323)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -2588,9 +2554,7 @@ async fn test_trade_too_much_meseta() { entity_gateway.set_character_meseta(&char1.id, Meseta(4000)).await.unwrap(); entity_gateway.set_character_meseta(&char2.id, Meseta(999000)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -2640,9 +2604,7 @@ async fn test_trade_invalid_amount_of_meseta() { entity_gateway.set_character_meseta(&char1.id, Meseta(4000)).await.unwrap(); entity_gateway.set_character_meseta(&char2.id, Meseta(999000)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -2692,9 +2654,7 @@ async fn test_trade_meseta_request_and_items_dont_match() { entity_gateway.set_character_meseta(&char1.id, Meseta(4000)).await.unwrap(); entity_gateway.set_character_meseta(&char2.id, Meseta(999000)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -2741,9 +2701,7 @@ async fn test_player_declined_trade() { let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -2789,9 +2747,7 @@ async fn test_back_out_of_trade_last_minute() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -2885,9 +2841,7 @@ async fn test_valid_trade_when_both_inventories_are_full() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -3027,9 +2981,7 @@ async fn test_invalid_trade_when_both_inventories_are_full() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -3133,9 +3085,7 @@ async fn test_client_tries_to_start_two_trades() { let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; let (_user2, _char3) = new_user_character(&mut entity_gateway, "a3", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; log_in_char(&mut ship, ClientId(3), "a3", "a").await; @@ -3166,9 +3116,7 @@ async fn test_client_tries_trading_with_client_already_trading() { let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; let (_user2, _char3) = new_user_character(&mut entity_gateway, "a3", "a", 1).await; - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; log_in_char(&mut ship, ClientId(3), "a3", "a").await; @@ -3223,9 +3171,7 @@ async fn test_add_then_remove_individual_item() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -3354,9 +3300,7 @@ async fn test_add_then_remove_stacked_item() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack1, p1_stack2])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -3489,9 +3433,7 @@ async fn test_add_then_remove_partial_stack() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack1, p1_stack2])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -3578,9 +3520,7 @@ async fn test_add_then_remove_meseta() { entity_gateway.set_character_meseta(&char1.id, Meseta(2323)).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -3679,9 +3619,7 @@ async fn test_items_to_trade_data_does_not_match() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -3762,9 +3700,7 @@ async fn test_items_to_trade_id_does_not_match() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -3836,9 +3772,7 @@ async fn test_stack_is_same_amount_in_request_and_items_to_trade() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -3910,9 +3844,7 @@ async fn test_stack_is_same_amount_in_request_and_items_to_trade2() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -4006,9 +3938,7 @@ async fn test_items_to_trade_count_less_than() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -4110,9 +4040,7 @@ async fn test_items_to_trade_count_greater_than() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -4218,9 +4146,7 @@ async fn test_items_to_trade_count_mismatch_with_meseta() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -4295,9 +4221,7 @@ async fn test_dropping_item_after_trade() { entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); - let mut ship = Box::new(ShipServerState::builder() - .gateway(entity_gateway.clone()) - .build()); + let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; -- 2.36.0 From ffd431cd3ba23e2fd1ffa68e8a825cc3b63b95e7 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 22:05:40 -0700 Subject: [PATCH 42/58] clippy --- src/bin/main.rs | 2 -- src/bin/ship.rs | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index 79f95be..e50db30 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -8,13 +8,11 @@ use elseware::patch::{PatchServerState, generate_patch_tree, load_config, load_m use elseware::ship::ship::ShipServerStateBuilder; use maps::Holiday; -use maps::maps::generate_free_roam_maps; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; use entity::character::NewCharacterEntity; use entity::item::{NewItemEntity, ItemDetail, InventoryItemEntity}; use entity::item; -use drops::StandardDropTable; fn setup_logger() { let colors = fern::colors::ColoredLevelConfig::new() diff --git a/src/bin/ship.rs b/src/bin/ship.rs index baf87c6..c021601 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -2,8 +2,6 @@ use log::info; use entity::gateway::postgres::PostgresGateway; use elseware::ship::ship::ShipServerStateBuilder; use networking::interserver::AuthToken; -use drops::StandardDropTable; -use maps::maps::generate_free_roam_maps; fn main() { let colors = fern::colors::ColoredLevelConfig::new() -- 2.36.0 From 76fd7e82f6856a797dab1a48d74a8a6bc1bfb6ec Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 23:03:44 -0700 Subject: [PATCH 43/58] add nullable item shops for faster test runtimes --- shops/Cargo.toml | 4 ++ shops/src/lib.rs | 80 ++++++++++++++++++++++- src/ship/packet/handler/direct_message.rs | 32 +++------ src/ship/ship.rs | 46 ++++--------- tests/common.rs | 20 ++++++ tests/test_bank.rs | 5 +- tests/test_shops.rs | 49 ++++++++++---- 7 files changed, 164 insertions(+), 72 deletions(-) diff --git a/shops/Cargo.toml b/shops/Cargo.toml index 495bf2f..25e3055 100644 --- a/shops/Cargo.toml +++ b/shops/Cargo.toml @@ -8,6 +8,10 @@ maps = { workspace = true } stats = { workspace = true } entity = { workspace = true } +async-std = { workspace = true } +async-trait = { workspace = true } +futures = { workspace = true } rand = { workspace = true } +rand_chacha = { workspace = true } toml = { workspace = true } serde = { workspace = true } \ No newline at end of file diff --git a/shops/src/lib.rs b/shops/src/lib.rs index 7a999b7..94abdec 100644 --- a/shops/src/lib.rs +++ b/shops/src/lib.rs @@ -2,7 +2,16 @@ mod weapon; mod tool; mod armor; +use async_std::sync::{Arc, Mutex}; +use futures::future::OptionFuture; +use std::collections::HashMap; use entity::item::ItemDetail; +use maps::room::Difficulty; +use entity::character::SectionID; + +pub use weapon::{WeaponShop, WeaponShopItem}; +pub use tool::{ToolShop, ToolShopItem}; +pub use armor::{ArmorShop, ArmorShopItem}; pub trait ShopItem { fn price(&self) -> usize; @@ -10,12 +19,77 @@ pub trait ShopItem { fn as_item(&self) -> ItemDetail; } +#[async_trait::async_trait] +pub trait ItemShops { + async fn generate_weapon_list(&self, difficulty: Difficulty, section_id: SectionID, char_level: usize) -> Option>; + async fn generate_tool_list(&self, char_level: usize) -> Vec; + async fn generate_armor_list(&self, char_level: usize) -> Vec; +} + + +#[derive(Clone)] +pub struct StandardItemShops { + weapon_shop: HashMap<(Difficulty, SectionID), Arc>>>, + tool_shop: Arc>>, + armor_shop: Arc>>, +} + +impl Default for StandardItemShops { + fn default() -> StandardItemShops { + let difficulty = [Difficulty::Normal, Difficulty::Hard, Difficulty::VeryHard, Difficulty::Ultimate]; + let section_id = [SectionID::Viridia, SectionID::Greenill, SectionID::Skyly, SectionID::Bluefull, SectionID::Purplenum, + SectionID::Pinkal, SectionID::Redria, SectionID::Oran, SectionID::Yellowboze, SectionID::Whitill]; + + let mut weapon_shop = HashMap::new(); + for d in difficulty.iter() { + for id in section_id.iter() { + weapon_shop.insert((*d, *id), Arc::new(Mutex::new(WeaponShop::new(*d, *id)))); + } + } + + StandardItemShops { + weapon_shop, + tool_shop: Arc::new(Mutex::new(ToolShop::default())), + armor_shop: Arc::new(Mutex::new(ArmorShop::default())), + } + } +} + +#[async_trait::async_trait] +impl ItemShops for StandardItemShops { + async fn generate_weapon_list(&self, difficulty: Difficulty, section_id: SectionID, char_level: usize) -> Option> { + OptionFuture::from( + self.weapon_shop + .get(&(difficulty, section_id)) + .map(|shop| async { + shop + .lock() + .await + .generate_weapon_list(char_level) + })).await + } + + async fn generate_tool_list(&self, char_level: usize) -> Vec { + self.tool_shop + .lock() + .await + .generate_tool_list(char_level) + } + + async fn generate_armor_list(&self, char_level: usize) -> Vec { + self.armor_shop + .lock() + .await + .generate_armor_list(char_level) + } +} + + + + pub enum ShopType { Weapon, Tool, Armor } -pub use weapon::{WeaponShop, WeaponShopItem}; -pub use tool::{ToolShop, ToolShopItem}; -pub use armor::{ArmorShop, ArmorShopItem}; diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index 090d77d..c93ae0d 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/src/ship/packet/handler/direct_message.rs @@ -1,11 +1,12 @@ use log::warn; +use async_std::sync::Arc; use rand::Rng; use rand::seq::SliceRandom; use libpso::packet::ship::*; use libpso::packet::messages::*; use stats::leveltable::LEVEL_TABLE; use networking::serverstate::ClientId; -use crate::ship::ship::{SendShipPacket, ShipError, Clients, ItemShops}; +use crate::ship::ship::{SendShipPacket, ShipError, Clients}; use location::ClientLocation; use drops::ItemDrop; use room::Rooms; @@ -14,7 +15,7 @@ use entity::gateway::EntityGateway; use entity::item; use libpso::utf8_to_utf16_array; use pktbuilder as builder; -use shops::{ShopItem, ToolShopItem, ArmorShopItem}; +use shops::{ItemShops, ShopItem, ToolShopItem, ArmorShopItem}; use items::state::{ItemState, ItemStateError}; use items::floor::{FloorType, FloorItemDetail}; use items::actions::TriggerCreateItem; @@ -320,45 +321,30 @@ pub async fn shop_request(id: ClientId, client_location: &ClientLocation, clients: &Clients, rooms: &Rooms, - shops: &ItemShops) + shops: &Arc>) -> Result, anyhow::Error> { - //let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?; let room_id = client_location.get_room(id).await?; - /* - let room = rooms.get(room_id.0) - .ok_or(ShipError::InvalidRoom(room_id.0 as u32))? - .as_ref() - .ok_or(ShipError::InvalidRoom(room_id.0 as u32))?; - */ let difficulty = rooms.with(room_id, |room| Box::pin(async move { room.mode.difficulty() })).await?; let shop_list = clients.with_mut(id, |client| { - let mut shops = shops.clone(); + let shops = shops.clone(); Box::pin(async move { let level = LEVEL_TABLE.get_level_from_exp(client.character.char_class, client.character.exp) as usize; match shop_request.shop_type { SHOP_OPTION_WEAPON => { - client.weapon_shop = shops.weapon_shop.get_mut(&(difficulty, client.character.section_id)) - .ok_or(ShipError::ShopError)? - .lock() + client.weapon_shop = shops.generate_weapon_list(difficulty, client.character.section_id, level) .await - .generate_weapon_list(level); + .ok_or(ShipError::ShopError)?; Ok(builder::message::shop_list(shop_request.shop_type, &client.weapon_shop)) }, SHOP_OPTION_TOOL => { - client.tool_shop = shops.tool_shop - .lock() - .await - .generate_tool_list(level); + client.tool_shop = shops.generate_tool_list(level).await; Ok(builder::message::shop_list(shop_request.shop_type, &client.tool_shop)) }, SHOP_OPTION_ARMOR => { - client.armor_shop = shops.armor_shop - .lock() - .await - .generate_armor_list(level); + client.armor_shop = shops.generate_armor_list(level).await; Ok(builder::message::shop_list(shop_request.shop_type, &client.armor_shop)) }, _ => { diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 3ee833f..efa026a 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -1,9 +1,8 @@ #![allow(dead_code, unused_must_use)] use std::net::Ipv4Addr; -use std::collections::HashMap; use async_std::channel; -use async_std::sync::{Arc, Mutex, RwLock}; +use async_std::sync::{Arc, RwLock}; use rand::Rng; use thiserror::Error; @@ -32,7 +31,7 @@ use maps::Holiday; use maps::area::MapAreaError; use maps::maps::{Maps, MapsError, generate_free_roam_maps}; use crate::ship::packet::handler; -use shops::{WeaponShop, ToolShop, ArmorShop}; +use shops::{ItemShops, StandardItemShops}; use trade::TradeState; use crate::ship::chatcommand; use pktbuilder::quest::{QUEST_CATEGORY_MENU_ID, QUEST_SELECT_MENU_ID}; @@ -296,34 +295,6 @@ impl SendServerPacket for SendShipPacket { } } -#[derive(Clone)] -pub struct ItemShops { - pub weapon_shop: HashMap<(Difficulty, SectionID), Arc>>>, - pub tool_shop: Arc>>, - pub armor_shop: Arc>>, -} - -impl Default for ItemShops { - fn default() -> ItemShops { - let difficulty = [Difficulty::Normal, Difficulty::Hard, Difficulty::VeryHard, Difficulty::Ultimate]; - let section_id = [SectionID::Viridia, SectionID::Greenill, SectionID::Skyly, SectionID::Bluefull, SectionID::Purplenum, - SectionID::Pinkal, SectionID::Redria, SectionID::Oran, SectionID::Yellowboze, SectionID::Whitill]; - - let mut weapon_shop = HashMap::new(); - for d in difficulty.iter() { - for id in section_id.iter() { - weapon_shop.insert((*d, *id), Arc::new(Mutex::new(WeaponShop::new(*d, *id)))); - } - } - - ItemShops { - weapon_shop, - tool_shop: Arc::new(Mutex::new(ToolShop::default())), - armor_shop: Arc::new(Mutex::new(ArmorShop::default())), - } - } -} - pub struct ShipServerStateBuilder { entity_gateway: Option, @@ -332,6 +303,7 @@ pub struct ShipServerStateBuilder { port: Option, auth_token: Option, event: Option, + shops: Option>, map_builder: Option Maps + Send + Sync>>, drop_table_builder: Option Box + Send + Sync>>, standard_quest_builder: Option Result + Send + Sync>>, @@ -348,6 +320,7 @@ impl Default for ShipServerStateBuilder port: None, auth_token: None, event: None, + shops: None, map_builder: None, drop_table_builder: None, standard_quest_builder: None, @@ -418,6 +391,12 @@ impl ShipServerStateBuilder { self } + #[must_use] + pub fn item_shops(mut self, item_shops: impl ItemShops + Send + Sync + 'static) -> ShipServerStateBuilder { + self.shops = Some(Box::new(item_shops)); + self + } + #[must_use] pub fn blocks(mut self, num_blocks: usize) -> ShipServerStateBuilder { self.num_blocks = num_blocks; @@ -433,7 +412,8 @@ impl ShipServerStateBuilder { item_state: items::state::ItemState::default(), ip: self.ip.unwrap_or_else(|| Ipv4Addr::new(127,0,0,1)), port: self.port.unwrap_or(SHIP_PORT), - shops: ItemShops::default(), + #[allow(clippy::box_default)] // this lint leads to another which just doesn't work + shops: Arc::new(self.shops.unwrap_or(Box::new(StandardItemShops::default()))), blocks: Blocks(blocks), event: self.event.unwrap_or(Holiday::None), map_builder: Arc::new(self.map_builder.unwrap_or(Box::new(generate_free_roam_maps))), @@ -476,7 +456,7 @@ pub struct ShipServerState { pub clients: Clients, name: String, pub(crate) item_state: items::state::ItemState, - shops: ItemShops, + shops: Arc>, pub blocks: Blocks, event: Holiday, diff --git a/tests/common.rs b/tests/common.rs index f28d318..f446d37 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -13,6 +13,7 @@ use maps::object::MapObject; use maps::monster::MonsterType; use quests::{QuestList, QuestLoadError}; use drops::{DropTable, ItemDropType}; +use shops::{ItemShops, WeaponShopItem, ToolShopItem, ArmorShopItem}; use entity::item; @@ -35,6 +36,23 @@ impl DropTable for NullDropTable { } } +struct NullItemShops; + +#[async_trait::async_trait] +impl ItemShops for NullItemShops { + async fn generate_weapon_list(&self, _difficulty: Difficulty, _section_id: SectionID, _char_level: usize) -> Option> { + Some(Vec::new()) + } + async fn generate_tool_list(&self, _char_level: usize) -> Vec { + Vec::new() + } + async fn generate_armor_list(&self, _char_level: usize) -> Vec { + Vec::new() + } +} + + + pub fn null_drop_table_builder(_episode: Episode, _difficult: Difficulty, _section_id: SectionID) -> Box { Box::new(NullDropTable) } @@ -46,6 +64,7 @@ pub fn standard_ship_buildable(gateway: EG) -> ShipS .government_quest_builder(Box::new(null_quest_builder)) .drop_table_builder(Box::new(null_drop_table_builder)) .map_builder(Box::new(null_free_roam_maps)) + .item_shops(NullItemShops) } pub fn standard_ship(gateway: EG) -> ShipServerState { @@ -55,6 +74,7 @@ pub fn standard_ship(gateway: EG) -> ShipServerState .government_quest_builder(Box::new(null_quest_builder)) .drop_table_builder(Box::new(null_drop_table_builder)) .map_builder(Box::new(null_free_roam_maps)) + .item_shops(NullItemShops) .build() } diff --git a/tests/test_bank.rs b/tests/test_bank.rs index 2a97d6b..07a6ee8 100644 --- a/tests/test_bank.rs +++ b/tests/test_bank.rs @@ -3,6 +3,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; +use shops::StandardItemShops; use libpso::packet::ship::*; use libpso::packet::messages::*; @@ -1538,7 +1539,9 @@ async fn test_withdraw_meseta_and_buy_a_few_monomates_with_it() { entity_gateway.set_character_meseta(&char1.id, item::Meseta(100)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; diff --git a/tests/test_shops.rs b/tests/test_shops.rs index 392fa5a..00d8f5c 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -4,6 +4,7 @@ use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; use maps::room::Difficulty; use items::state::ItemStateError; +use shops::StandardItemShops; use libpso::packet::ship::*; use libpso::packet::messages::*; @@ -20,7 +21,9 @@ async fn test_player_opens_weapon_shop() { char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -48,7 +51,9 @@ async fn test_player_opens_tool_shop() { char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -76,7 +81,9 @@ async fn test_player_opens_armor_shop() { char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -105,7 +112,9 @@ async fn test_player_buys_from_weapon_shop() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -141,7 +150,9 @@ async fn test_player_buys_from_tool_shop() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -176,7 +187,9 @@ async fn test_player_buys_multiple_from_tool_shop() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -215,7 +228,9 @@ async fn test_player_buys_from_armor_shop() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -293,7 +308,9 @@ async fn test_other_clients_see_purchase() { entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -342,7 +359,9 @@ async fn test_other_clients_see_stacked_purchase() { ), }).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -415,7 +434,9 @@ async fn test_player_double_buys_from_tool_shop() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -478,7 +499,9 @@ async fn test_techs_disappear_from_shop_when_bought() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -538,7 +561,9 @@ async fn test_units_disappear_from_shop_when_bought() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); - let mut ship = standard_ship(entity_gateway.clone()); + let mut ship = standard_ship_buildable(entity_gateway.clone()) + .item_shops(StandardItemShops::default()) + .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; -- 2.36.0 From 579f10f08ea7e65f8288961a07070510838da089 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 23:11:58 -0700 Subject: [PATCH 44/58] don't load shops for real this time --- src/ship/ship.rs | 11 +++++------ tests/common.rs | 12 +++++------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/ship/ship.rs b/src/ship/ship.rs index efa026a..f9816c2 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -412,14 +412,13 @@ impl ShipServerStateBuilder { item_state: items::state::ItemState::default(), ip: self.ip.unwrap_or_else(|| Ipv4Addr::new(127,0,0,1)), port: self.port.unwrap_or(SHIP_PORT), - #[allow(clippy::box_default)] // this lint leads to another which just doesn't work - shops: Arc::new(self.shops.unwrap_or(Box::new(StandardItemShops::default()))), + shops: Arc::new(self.shops.unwrap_or_else(|| Box::::default())), blocks: Blocks(blocks), event: self.event.unwrap_or(Holiday::None), - map_builder: Arc::new(self.map_builder.unwrap_or(Box::new(generate_free_roam_maps))), - drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or(Box::new(StandardDropTable::new))), - standard_quest_builder: Arc::new(self.standard_quest_builder.unwrap_or(Box::new(load_standard_quests))), - government_quest_builder: Arc::new(self.government_quest_builder.unwrap_or(Box::new(load_government_quests))), + map_builder: Arc::new(self.map_builder.unwrap_or_else(|| Box::new(generate_free_roam_maps))), + drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or_else(|| Box::new(StandardDropTable::new))), + standard_quest_builder: Arc::new(self.standard_quest_builder.unwrap_or_else(|| Box::new(load_standard_quests))), + government_quest_builder: Arc::new(self.government_quest_builder.unwrap_or_else(|| Box::new(load_government_quests))), auth_token: self.auth_token.unwrap_or_else(|| AuthToken("".into())), ship_list: Arc::new(RwLock::new(Vec::new())), diff --git a/tests/common.rs b/tests/common.rs index f446d37..36c0d7a 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -36,10 +36,14 @@ impl DropTable for NullDropTable { } } +pub fn null_drop_table_builder(_episode: Episode, _difficult: Difficulty, _section_id: SectionID) -> Box { + Box::new(NullDropTable) +} + struct NullItemShops; #[async_trait::async_trait] -impl ItemShops for NullItemShops { +impl ItemShops for NullItemShops { async fn generate_weapon_list(&self, _difficulty: Difficulty, _section_id: SectionID, _char_level: usize) -> Option> { Some(Vec::new()) } @@ -51,12 +55,6 @@ impl ItemShops for NullItemShops { } } - - -pub fn null_drop_table_builder(_episode: Episode, _difficult: Difficulty, _section_id: SectionID) -> Box { - Box::new(NullDropTable) -} - pub fn standard_ship_buildable(gateway: EG) -> ShipServerStateBuilder { ShipServerState::builder() .gateway(gateway) -- 2.36.0 From ff2601a8243506d1796a371213d8abf8d19aef96 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 11 Nov 2023 23:28:02 -0700 Subject: [PATCH 45/58] try removing incremental build files to see if it helps ci disk usage --- .drone.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index c57acb0..e6c144b 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,11 +1,14 @@ --- kind: pipeline type: docker -name: test elseware +name: test elseware concurrency: limit: 1 +environment: + CARGO_INCREMENTAL: false + steps: - name: clean cache image: rustlang/rust:nightly -- 2.36.0 From 3934aa3d4ee8756ef9d0d81835a74424125aebb7 Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 12 Nov 2023 00:08:38 -0700 Subject: [PATCH 46/58] try using cargo-prune instead of cargo-sweep --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index e6c144b..49ef008 100644 --- a/.drone.yml +++ b/.drone.yml @@ -18,7 +18,7 @@ steps: - name: target-cache path: /drone/src/target commands: - - cargo sweep --maxsize 12GiB + - cargo prune - name: build image: rustlang/rust:nightly volumes: -- 2.36.0 From 3c2c325968db17f319038b309a3b49413829ff20 Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 12 Nov 2023 00:25:00 -0700 Subject: [PATCH 47/58] fix a few warnings in tests --- tests/common.rs | 2 +- tests/test_bank.rs | 2 +- tests/test_character.rs | 6 +++--- tests/test_exp_gain.rs | 2 +- tests/test_item_actions.rs | 2 +- tests/test_item_drop.rs | 2 +- tests/test_item_id.rs | 2 +- tests/test_item_pickup.rs | 2 +- tests/test_item_use.rs | 2 +- tests/test_mags.rs | 2 +- tests/test_rooms.rs | 3 +-- tests/test_shops.rs | 2 +- tests/test_trade.rs | 2 +- 13 files changed, 15 insertions(+), 16 deletions(-) diff --git a/tests/common.rs b/tests/common.rs index 36c0d7a..db91ab8 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -77,7 +77,7 @@ pub fn standard_ship(gateway: EG) -> ShipServerState } //TODO: remove kb_conf_preset -pub async fn new_user_character(entity_gateway: &mut EG, username: &str, password: &str, kb_conf_preset: usize) -> (UserAccountEntity, CharacterEntity) { +pub async fn new_user_character(entity_gateway: &mut EG, username: &str, password: &str, _kb_conf_preset: usize) -> (UserAccountEntity, CharacterEntity) { let new_user = NewUserAccountEntity { email: format!("{}@pso.com", username), username: username.into(), diff --git a/tests/test_bank.rs b/tests/test_bank.rs index 07a6ee8..443da34 100644 --- a/tests/test_bank.rs +++ b/tests/test_bank.rs @@ -2,7 +2,7 @@ use std::collections::BTreeSet; use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; +use elseware::ship::ship::{RecvShipPacket, SendShipPacket}; use shops::StandardItemShops; use libpso::packet::ship::*; diff --git a/tests/test_character.rs b/tests/test_character.rs index ee78434..0c8cecf 100644 --- a/tests/test_character.rs +++ b/tests/test_character.rs @@ -1,8 +1,8 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::ship::ship::{ShipServerState, RecvShipPacket}; +use elseware::ship::ship::RecvShipPacket; -use libpso::character::settings::{DEFAULT_KEYBOARD_CONFIG1, DEFAULT_KEYBOARD_CONFIG2, DEFAULT_KEYBOARD_CONFIG3, DEFAULT_KEYBOARD_CONFIG4}; +use libpso::character::settings::{DEFAULT_KEYBOARD_CONFIG1, DEFAULT_KEYBOARD_CONFIG4}; use libpso::packet::ship::*; #[path = "common.rs"] @@ -33,7 +33,7 @@ async fn test_save_options() { async fn test_change_keyboard_mappings() { let mut entity_gateway = InMemoryGateway::default(); - let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 2).await; + let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 2).await; let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; diff --git a/tests/test_exp_gain.rs b/tests/test_exp_gain.rs index 5e4bcf9..ae49fce 100644 --- a/tests/test_exp_gain.rs +++ b/tests/test_exp_gain.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use stats::leveltable::CharacterLevelTable; -use elseware::ship::ship::{ShipServerState, SendShipPacket, RecvShipPacket}; +use elseware::ship::ship::{SendShipPacket, RecvShipPacket}; use maps::variant::{MapVariant, MapVariantMode}; use maps::maps::Maps; use maps::area::MapArea; diff --git a/tests/test_item_actions.rs b/tests/test_item_actions.rs index 0212d08..758aa10 100644 --- a/tests/test_item_actions.rs +++ b/tests/test_item_actions.rs @@ -1,6 +1,6 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::ship::ship::{ShipServerState, RecvShipPacket}; +use elseware::ship::ship::RecvShipPacket; use entity::item; use libpso::packet::ship::*; diff --git a/tests/test_item_drop.rs b/tests/test_item_drop.rs index bac45ac..0c700bb 100644 --- a/tests/test_item_drop.rs +++ b/tests/test_item_drop.rs @@ -1,6 +1,6 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::InMemoryGateway; -use elseware::ship::ship::{ShipServerState, SendShipPacket, RecvShipPacket}; +use elseware::ship::ship::{SendShipPacket, RecvShipPacket}; use maps::monster::MonsterType; use drops::{StandardDropTable, MonsterDropStats, MonsterDropType}; use drops::rare_drop_table::{RareDropTable, RareDropRate, RareDropItem}; diff --git a/tests/test_item_id.rs b/tests/test_item_id.rs index ff8f4ad..ad2f860 100644 --- a/tests/test_item_id.rs +++ b/tests/test_item_id.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::{ShipServerState, RecvShipPacket}; +use elseware::ship::ship::RecvShipPacket; use libpso::packet::ship::*; use libpso::packet::messages::*; diff --git a/tests/test_item_pickup.rs b/tests/test_item_pickup.rs index d1ba62e..3ec0b9c 100644 --- a/tests/test_item_pickup.rs +++ b/tests/test_item_pickup.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::{ShipServerState, RecvShipPacket}; +use elseware::ship::ship::RecvShipPacket; use libpso::packet::ship::*; use libpso::packet::messages::*; diff --git a/tests/test_item_use.rs b/tests/test_item_use.rs index 0f28a18..13f2310 100644 --- a/tests/test_item_use.rs +++ b/tests/test_item_use.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::{ShipServerState, RecvShipPacket}; +use elseware::ship::ship::RecvShipPacket; use entity::character::TechLevel; use libpso::packet::ship::*; diff --git a/tests/test_mags.rs b/tests/test_mags.rs index 963e71a..dac0e06 100644 --- a/tests/test_mags.rs +++ b/tests/test_mags.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::{ShipServerState, RecvShipPacket}; +use elseware::ship::ship::RecvShipPacket; use entity::character::{CharacterClass, SectionID}; use libpso::packet::ship::*; diff --git a/tests/test_rooms.rs b/tests/test_rooms.rs index ced3e27..447ea7b 100644 --- a/tests/test_rooms.rs +++ b/tests/test_rooms.rs @@ -1,6 +1,6 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; +use elseware::ship::ship::{RecvShipPacket, SendShipPacket}; use libpso::packet::ship::*; //use libpso::packet::messages::*; @@ -16,7 +16,6 @@ async fn test_set_valid_quest_group() { let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let mut ship = standard_ship_buildable(entity_gateway.clone()) .standard_quest_builder(Box::new(quests::load_standard_quests)) - .government_quest_builder(Box::new(quests::load_government_quests)) .build(); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; diff --git a/tests/test_shops.rs b/tests/test_shops.rs index 00d8f5c..cfcb749 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; +use elseware::ship::ship::{RecvShipPacket, SendShipPacket}; use maps::room::Difficulty; use items::state::ItemStateError; use shops::StandardItemShops; diff --git a/tests/test_trade.rs b/tests/test_trade.rs index ec4fb3c..4a08d0a 100644 --- a/tests/test_trade.rs +++ b/tests/test_trade.rs @@ -2,7 +2,7 @@ use std::convert::TryInto; use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket, ShipError}; +use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; use entity::item::{Meseta, ItemEntity, InventoryItemEntity}; use elseware::ship::packet::handler::trade::TradeError; -- 2.36.0 From 0a0542f642a3734053c6bf5cf2ec58318f294af0 Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 12 Nov 2023 00:46:02 -0700 Subject: [PATCH 48/58] why did that arg ever exist anyway --- tests/common.rs | 2 +- tests/test_bank.rs | 86 ++++++++++---------- tests/test_character.rs | 2 +- tests/test_exp_gain.rs | 10 +-- tests/test_item_actions.rs | 6 +- tests/test_item_drop.rs | 10 +-- tests/test_item_id.rs | 12 +-- tests/test_item_pickup.rs | 42 +++++----- tests/test_item_use.rs | 16 ++-- tests/test_mags.rs | 8 +- tests/test_rooms.rs | 16 ++-- tests/test_shops.rs | 58 +++++++------- tests/test_trade.rs | 156 ++++++++++++++++++------------------- 13 files changed, 212 insertions(+), 212 deletions(-) diff --git a/tests/common.rs b/tests/common.rs index db91ab8..e2a3555 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -77,7 +77,7 @@ pub fn standard_ship(gateway: EG) -> ShipServerState } //TODO: remove kb_conf_preset -pub async fn new_user_character(entity_gateway: &mut EG, username: &str, password: &str, _kb_conf_preset: usize) -> (UserAccountEntity, CharacterEntity) { +pub async fn new_user_character(entity_gateway: &mut EG, username: &str, password: &str) -> (UserAccountEntity, CharacterEntity) { let new_user = NewUserAccountEntity { email: format!("{}@pso.com", username), username: username.into(), diff --git a/tests/test_bank.rs b/tests/test_bank.rs index 443da34..a3ad3e8 100644 --- a/tests/test_bank.rs +++ b/tests/test_bank.rs @@ -16,8 +16,8 @@ use common::*; async fn test_bank_items_sent_in_character_login() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let item = entity_gateway.create_item( item::NewItemEntity { @@ -49,8 +49,8 @@ async fn test_bank_items_sent_in_character_login() { async fn test_request_bank_items() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut bank = Vec::new(); for _ in 0..3 { @@ -95,8 +95,8 @@ async fn test_request_bank_items() { async fn test_request_stacked_bank_items() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut monomates = Vec::new(); for _ in 0..3usize { @@ -136,8 +136,8 @@ async fn test_request_stacked_bank_items() { async fn test_request_bank_items_sorted() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let item1 = entity_gateway.create_item( item::NewItemEntity { @@ -200,8 +200,8 @@ async fn test_request_bank_items_sorted() { async fn test_deposit_individual_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let item0 = entity_gateway.create_item( item::NewItemEntity { @@ -277,8 +277,8 @@ async fn test_deposit_individual_item() { async fn test_deposit_stacked_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut monomates = Vec::new(); for _ in 0..3usize { @@ -336,8 +336,8 @@ async fn test_deposit_stacked_item() { async fn test_deposit_partial_stacked_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut monomates = Vec::new(); for _ in 0..3usize { @@ -404,8 +404,8 @@ async fn test_deposit_partial_stacked_item() { async fn test_deposit_stacked_item_with_stack_already_in_bank() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut bank_monomates = Vec::new(); let mut inventory_monomates = Vec::new(); @@ -474,7 +474,7 @@ async fn test_deposit_stacked_item_with_stack_already_in_bank() { async fn test_deposit_stacked_item_with_full_stack_in_bank() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut inventory_monomates = Vec::new(); for _ in 0..2usize { @@ -544,7 +544,7 @@ async fn test_deposit_stacked_item_with_full_stack_in_bank() { async fn test_deposit_individual_item_in_full_bank() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut inventory = Vec::new(); inventory.push(entity_gateway.create_item( @@ -616,7 +616,7 @@ async fn test_deposit_individual_item_in_full_bank() { async fn test_deposit_stacked_item_in_full_bank() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut monomates = Vec::new(); for _ in 0..2usize { @@ -687,7 +687,7 @@ async fn test_deposit_stacked_item_in_full_bank() { async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut monomates = Vec::new(); for _ in 0..2usize { @@ -768,7 +768,7 @@ async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() { async fn test_deposit_meseta() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap(); let mut ship = standard_ship(entity_gateway.clone()); @@ -802,7 +802,7 @@ async fn test_deposit_meseta() { async fn test_deposit_too_much_meseta() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(999980)).await.unwrap(); @@ -839,7 +839,7 @@ async fn test_deposit_too_much_meseta() { async fn test_deposit_meseta_when_bank_is_maxed() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(999999)).await.unwrap(); @@ -877,8 +877,8 @@ async fn test_deposit_meseta_when_bank_is_maxed() { async fn test_withdraw_individual_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut bank = Vec::new(); bank.push(entity_gateway.create_item( @@ -937,8 +937,8 @@ async fn test_withdraw_individual_item() { async fn test_withdraw_stacked_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut monomates = Vec::new(); for _ in 0..3usize { @@ -995,8 +995,8 @@ async fn test_withdraw_stacked_item() { async fn test_withdraw_partial_stacked_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut monomates = Vec::new(); for _ in 0..3usize { @@ -1059,8 +1059,8 @@ async fn test_withdraw_partial_stacked_item() { async fn test_withdraw_stacked_item_with_stack_already_in_inventory() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut inventory_monomates = Vec::new(); let mut bank_monomates = Vec::new(); @@ -1131,7 +1131,7 @@ async fn test_withdraw_stacked_item_with_stack_already_in_inventory() { async fn test_withdraw_stacked_item_with_full_stack_in_inventory() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut bank_monomates = Vec::new(); for _ in 0..2usize { @@ -1201,7 +1201,7 @@ async fn test_withdraw_stacked_item_with_full_stack_in_inventory() { async fn test_withdraw_individual_item_in_full_inventory() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut bank = Vec::new(); bank.push(entity_gateway.create_item( @@ -1269,7 +1269,7 @@ async fn test_withdraw_individual_item_in_full_inventory() { async fn test_withdraw_stacked_item_in_full_inventory() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut monomates = Vec::new(); for _ in 0..2usize { @@ -1341,7 +1341,7 @@ async fn test_withdraw_stacked_item_in_full_inventory() { async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut bank_item = Vec::new(); for _ in 0..2usize { @@ -1425,7 +1425,7 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() { async fn test_withdraw_meseta() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap(); let mut ship = standard_ship(entity_gateway.clone()); @@ -1459,7 +1459,7 @@ async fn test_withdraw_meseta() { async fn test_withdraw_too_much_meseta() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(999980)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap(); @@ -1496,7 +1496,7 @@ async fn test_withdraw_too_much_meseta() { async fn test_withdraw_meseta_inventory_is_maxed() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap(); @@ -1535,7 +1535,7 @@ async fn test_withdraw_meseta_inventory_is_maxed() { async fn test_withdraw_meseta_and_buy_a_few_monomates_with_it() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(100)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap(); @@ -1587,7 +1587,7 @@ async fn test_withdraw_meseta_and_buy_a_few_monomates_with_it() { async fn test_deposit_items_into_shared_banks() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let item0 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Saber).as_new()).await.unwrap(); let item1 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Buster).as_new()).await.unwrap(); @@ -1709,7 +1709,7 @@ async fn test_deposit_items_into_shared_banks() { async fn test_deposit_meseta_into_shared_banks() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap(); let mut ship = standard_ship(entity_gateway.clone()); @@ -1784,7 +1784,7 @@ async fn test_deposit_meseta_into_shared_banks() { async fn test_withdraw_items_from_shared_banks() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let item0 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Saber).as_new()).await.unwrap(); let item1 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Buster).as_new()).await.unwrap(); @@ -1894,7 +1894,7 @@ async fn test_withdraw_items_from_shared_banks() { async fn test_withdraw_meseta_from_shared_banks() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Shared(item::BankName("asdf".into())), item::Meseta(300)).await.unwrap(); entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Shared(item::BankName("qwer".into())), item::Meseta(300)).await.unwrap(); diff --git a/tests/test_character.rs b/tests/test_character.rs index 0c8cecf..fb68d80 100644 --- a/tests/test_character.rs +++ b/tests/test_character.rs @@ -13,7 +13,7 @@ use common::*; async fn test_save_options() { let mut entity_gateway = InMemoryGateway::default(); - let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; diff --git a/tests/test_exp_gain.rs b/tests/test_exp_gain.rs index ae49fce..da30c8a 100644 --- a/tests/test_exp_gain.rs +++ b/tests/test_exp_gain.rs @@ -19,7 +19,7 @@ use common::*; async fn test_character_gains_exp() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut ship = standard_ship_buildable(entity_gateway.clone()) .map_builder(Box::new(|_room_mode, _event| { @@ -52,7 +52,7 @@ async fn test_character_gains_exp() { async fn test_character_levels_up() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; char1.exp = 49; entity_gateway.save_character(&char1).await.unwrap(); @@ -90,7 +90,7 @@ async fn test_character_levels_up() { async fn test_character_levels_up_multiple_times() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut ship = standard_ship_buildable(entity_gateway.clone()) .map_builder(Box::new(|_room_mode, _event| { @@ -125,8 +125,8 @@ async fn test_character_levels_up_multiple_times() { async fn test_one_character_gets_full_exp_and_other_attacker_gets_partial() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut ship = standard_ship_buildable(entity_gateway.clone()) .map_builder(Box::new(|_room_mode, _event| { diff --git a/tests/test_item_actions.rs b/tests/test_item_actions.rs index 758aa10..2072403 100644 --- a/tests/test_item_actions.rs +++ b/tests/test_item_actions.rs @@ -14,7 +14,7 @@ use common::*; async fn test_equip_unit_from_equip_menu() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( @@ -89,7 +89,7 @@ async fn test_equip_unit_from_equip_menu() { async fn test_unequip_armor_with_units() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( @@ -155,7 +155,7 @@ async fn test_unequip_armor_with_units() { async fn test_sort_items() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( diff --git a/tests/test_item_drop.rs b/tests/test_item_drop.rs index 0c700bb..bcf4165 100644 --- a/tests/test_item_drop.rs +++ b/tests/test_item_drop.rs @@ -20,7 +20,7 @@ use common::*; #[async_std::test] async fn test_enemy_drops_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut ship = standard_ship_buildable(entity_gateway.clone()) .map_builder(Box::new(|_room_mode, _event| { @@ -74,8 +74,8 @@ async fn test_enemy_drops_item() { #[async_std::test] async fn test_enemy_drops_item_for_two_players() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut ship = standard_ship_buildable(entity_gateway.clone()) .map_builder(Box::new(|_room_mode, _event| { @@ -141,8 +141,8 @@ async fn test_enemy_drops_item_for_two_players() { #[async_std::test] async fn test_enemy_drops_item_for_two_players_and_pick_up() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut ship = standard_ship_buildable(entity_gateway.clone()) .map_builder(Box::new(|_room_mode, _event| { diff --git a/tests/test_item_id.rs b/tests/test_item_id.rs index ad2f860..d887af4 100644 --- a/tests/test_item_id.rs +++ b/tests/test_item_id.rs @@ -14,8 +14,8 @@ use common::*; #[async_std::test] async fn test_use_monomate_after_leaving_and_rejoining_room() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_items = Vec::new(); for tool in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter() { @@ -107,9 +107,9 @@ async fn test_use_monomate_after_leaving_and_rejoining_room() { #[async_std::test] async fn test_using_some_monomates_after_a_convoluted_series_of_leaves_and_joins() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; - let (_user3, char3) = new_user_character(&mut entity_gateway, "a3", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; + let (_user3, char3) = new_user_character(&mut entity_gateway, "a3", "a").await; let mut p1_items = Vec::new(); for tool in vec![item::tool::ToolType::Monofluid, item::tool::ToolType::Difluid, item::tool::ToolType::Trifluid].into_iter() { @@ -294,7 +294,7 @@ async fn test_using_some_monomates_after_a_convoluted_series_of_leaves_and_joins #[async_std::test] async fn test_depositing_a_full_stack_then_withdrawing_part() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_items = Vec::new(); for tool in vec![item::tool::ToolType::Monofluid, item::tool::ToolType::Difluid, item::tool::ToolType::Trifluid].into_iter() { diff --git a/tests/test_item_pickup.rs b/tests/test_item_pickup.rs index 3ec0b9c..7788ffb 100644 --- a/tests/test_item_pickup.rs +++ b/tests/test_item_pickup.rs @@ -14,8 +14,8 @@ use common::*; async fn test_pick_up_individual_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( @@ -83,8 +83,8 @@ async fn test_pick_up_individual_item() { async fn test_pick_up_item_stack_of_items_already_in_inventory() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_monomate = Vec::new(); p1_monomate.push(entity_gateway.create_item( @@ -157,8 +157,8 @@ async fn test_pick_up_item_stack_of_items_already_in_inventory() { async fn test_pick_up_item_stack_of_items_not_already_held() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p2_monomate = Vec::new(); p2_monomate.push(entity_gateway.create_item( @@ -214,8 +214,8 @@ async fn test_pick_up_item_stack_of_items_not_already_held() { async fn test_pick_up_meseta_when_inventory_full() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_items = Vec::new(); for _ in 0..30usize { @@ -285,8 +285,8 @@ async fn test_pick_up_meseta_when_inventory_full() { async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_inv = Vec::new(); for _slot in 0..29usize { @@ -366,8 +366,8 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { async fn test_can_not_pick_up_item_when_inventory_full() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_inv = Vec::new(); for _slot in 0..30usize { @@ -454,7 +454,7 @@ async fn test_can_not_pick_up_item_when_inventory_full() { async fn test_can_not_drop_more_meseta_than_is_held() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap(); @@ -492,8 +492,8 @@ async fn test_can_not_drop_more_meseta_than_is_held() { async fn test_pick_up_stack_that_would_exceed_stack_limit() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_monomates = Vec::new(); for _ in 0..6usize { @@ -564,8 +564,8 @@ async fn test_pick_up_stack_that_would_exceed_stack_limit() { async fn test_can_not_pick_up_meseta_when_full() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); entity_gateway.set_character_meseta(&char2.id, item::Meseta(300)).await.unwrap(); @@ -617,8 +617,8 @@ async fn test_can_not_pick_up_meseta_when_full() { async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(999998)).await.unwrap(); entity_gateway.set_character_meseta(&char2.id, item::Meseta(300)).await.unwrap(); @@ -669,8 +669,8 @@ async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() { async fn test_player_drops_partial_stack_and_other_player_picks_it_up() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut monomates = Vec::new(); for _ in 0..5usize { diff --git a/tests/test_item_use.rs b/tests/test_item_use.rs index 13f2310..a117da7 100644 --- a/tests/test_item_use.rs +++ b/tests/test_item_use.rs @@ -16,7 +16,7 @@ use common::*; async fn test_use_monomate() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_items = Vec::new(); for tool in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter() { @@ -61,7 +61,7 @@ async fn test_use_monomate() { async fn test_use_monomate_twice() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_items = Vec::new(); for tool in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter() { @@ -111,7 +111,7 @@ async fn test_use_monomate_twice() { async fn test_use_last_monomate() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); for tool in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter() { @@ -151,7 +151,7 @@ async fn test_use_last_monomate() { async fn test_use_nonstackable_tool() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_items = Vec::new(); p1_items.push(entity_gateway.create_item( @@ -184,7 +184,7 @@ async fn test_use_nonstackable_tool() { async fn test_use_materials() { let mut entity_gateway = InMemoryGateway::default(); - let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); for tool in vec![item::tool::ToolType::PowerMaterial, item::tool::ToolType::LuckMaterial].into_iter() { @@ -244,7 +244,7 @@ async fn test_use_materials() { #[async_std::test] async fn test_jackolantern() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let p1_inv = vec![ item::InventoryItemEntity::Stacked( @@ -297,7 +297,7 @@ async fn test_jackolantern() { async fn test_use_barta_1() { let mut entity_gateway = InMemoryGateway::default(); - let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let inv = vec![ entity_gateway.create_item( @@ -365,7 +365,7 @@ async fn test_use_barta_1() { async fn test_use_monogrinder() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let saber = entity_gateway.create_item( item::NewItemEntity { diff --git a/tests/test_mags.rs b/tests/test_mags.rs index dac0e06..a4ee763 100644 --- a/tests/test_mags.rs +++ b/tests/test_mags.rs @@ -15,7 +15,7 @@ use common::*; async fn test_mag_feed() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mag = entity_gateway.create_item( item::NewItemEntity { @@ -85,8 +85,8 @@ async fn test_mag_feed() { async fn test_mag_change_owner() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await; char1.char_class = CharacterClass::RAmarl; char1.section_id = SectionID::Redria; entity_gateway.save_character(&char1).await.unwrap(); @@ -148,7 +148,7 @@ async fn test_mag_change_owner() { async fn test_mag_cell() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mag = entity_gateway.create_item( item::NewItemEntity { diff --git a/tests/test_rooms.rs b/tests/test_rooms.rs index 447ea7b..3d073e4 100644 --- a/tests/test_rooms.rs +++ b/tests/test_rooms.rs @@ -13,7 +13,7 @@ use common::*; #[async_std::test] async fn test_set_valid_quest_group() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut ship = standard_ship_buildable(entity_gateway.clone()) .standard_quest_builder(Box::new(quests::load_standard_quests)) .build(); @@ -33,7 +33,7 @@ async fn test_set_valid_quest_group() { #[async_std::test] async fn test_set_invalid_quest_group() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut ship = standard_ship_buildable(entity_gateway.clone()) .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) @@ -56,10 +56,10 @@ async fn test_set_invalid_quest_group() { #[async_std::test] async fn test_get_room_info() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; _char1.name = String::from("GODmar"); entity_gateway.save_character(&_char1).await.unwrap(); - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -77,8 +77,8 @@ async fn test_get_room_info() { #[async_std::test] async fn test_cannot_get_room_info_after_room_is_closed() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -97,8 +97,8 @@ async fn test_cannot_get_room_info_after_room_is_closed() { #[async_std::test] async fn test_cannot_join_room_after_its_closed() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; diff --git a/tests/test_shops.rs b/tests/test_shops.rs index cfcb749..4855db4 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -17,7 +17,7 @@ use common::*; async fn test_player_opens_weapon_shop() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); @@ -47,7 +47,7 @@ async fn test_player_opens_weapon_shop() { async fn test_player_opens_tool_shop() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); @@ -77,7 +77,7 @@ async fn test_player_opens_tool_shop() { async fn test_player_opens_armor_shop() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); @@ -107,7 +107,7 @@ async fn test_player_opens_armor_shop() { async fn test_player_buys_from_weapon_shop() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); @@ -145,7 +145,7 @@ async fn test_player_buys_from_weapon_shop() { async fn test_player_buys_from_tool_shop() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); @@ -182,7 +182,7 @@ async fn test_player_buys_from_tool_shop() { async fn test_player_buys_multiple_from_tool_shop() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); @@ -223,7 +223,7 @@ async fn test_player_buys_multiple_from_tool_shop() { async fn test_player_buys_from_armor_shop() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); @@ -260,7 +260,7 @@ async fn test_player_buys_from_armor_shop() { async fn test_player_sells_3_attr_weapon_to_shop() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -302,8 +302,8 @@ async fn test_player_sells_3_attr_weapon_to_shop() { async fn test_other_clients_see_purchase() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; char1.exp = 80000000; entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); entity_gateway.save_character(&char1).await.unwrap(); @@ -345,8 +345,8 @@ async fn test_other_clients_see_purchase() { async fn test_other_clients_see_stacked_purchase() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); @@ -396,7 +396,7 @@ async fn test_other_clients_see_stacked_purchase() { async fn test_buying_item_without_enough_mseseta() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; @@ -429,7 +429,7 @@ async fn test_buying_item_without_enough_mseseta() { async fn test_player_double_buys_from_tool_shop() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); @@ -494,7 +494,7 @@ async fn test_player_double_buys_from_tool_shop() { async fn test_techs_disappear_from_shop_when_bought() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); @@ -556,7 +556,7 @@ async fn test_techs_disappear_from_shop_when_bought() { async fn test_units_disappear_from_shop_when_bought() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); @@ -617,7 +617,7 @@ async fn test_units_disappear_from_shop_when_bought() { async fn test_player_sells_untekked_weapon() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -659,7 +659,7 @@ async fn test_player_sells_untekked_weapon() { async fn test_player_sells_rare_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -701,7 +701,7 @@ async fn test_player_sells_rare_item() { async fn test_player_sells_partial_photon_drop_stack() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -742,7 +742,7 @@ async fn test_player_sells_partial_photon_drop_stack() { async fn test_player_sells_basic_frame() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -781,7 +781,7 @@ async fn test_player_sells_basic_frame() { async fn test_player_sells_max_frame() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -820,7 +820,7 @@ async fn test_player_sells_max_frame() { async fn test_player_sells_basic_barrier() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -858,7 +858,7 @@ async fn test_player_sells_basic_barrier() { async fn test_player_sells_max_barrier() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -896,7 +896,7 @@ async fn test_player_sells_max_barrier() { async fn test_player_sells_1_star_minusminus_unit() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -933,7 +933,7 @@ async fn test_player_sells_1_star_minusminus_unit() { async fn test_player_sells_5_star_plusplus_unit() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -970,7 +970,7 @@ async fn test_player_sells_5_star_plusplus_unit() { async fn test_player_sells_rare_frame() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -1009,7 +1009,7 @@ async fn test_player_sells_rare_frame() { async fn test_player_sells_rare_barrier() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -1047,7 +1047,7 @@ async fn test_player_sells_rare_barrier() { async fn test_player_sells_rare_unit() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut p1_inv = Vec::new(); @@ -1084,7 +1084,7 @@ async fn test_player_sells_rare_unit() { async fn test_player_cant_sell_if_meseta_would_go_over_max() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.set_character_meseta(&char1.id, item::Meseta(999995)).await.unwrap(); let mut p1_inv = Vec::new(); diff --git a/tests/test_trade.rs b/tests/test_trade.rs index 4a08d0a..d35d31b 100644 --- a/tests/test_trade.rs +++ b/tests/test_trade.rs @@ -113,8 +113,8 @@ impl TradeItemBuilder { async fn test_trade_one_individual_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( @@ -212,8 +212,8 @@ async fn test_trade_one_individual_item() { async fn test_trade_player2_to_player1() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p2_inv = Vec::new(); p2_inv.push(entity_gateway.create_item( @@ -311,8 +311,8 @@ async fn test_trade_player2_to_player1() { async fn test_reverse_trade_ack_order() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( @@ -410,8 +410,8 @@ async fn test_reverse_trade_ack_order() { async fn test_trade_one_stacked_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -512,8 +512,8 @@ async fn test_trade_one_stacked_item() { async fn test_trade_partial_stacked_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -617,8 +617,8 @@ async fn test_trade_partial_stacked_item() { async fn test_trade_individual_both() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_inv = vec![ entity_gateway.create_item( @@ -780,8 +780,8 @@ async fn test_trade_individual_both() { async fn test_trade_stacked_both() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -948,8 +948,8 @@ async fn test_trade_stacked_both() { async fn test_trade_partial_stack_both() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -1122,8 +1122,8 @@ async fn test_trade_partial_stack_both() { async fn test_trade_same_stacked_item_to_eachother() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack = futures::future::join_all((0..3).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -1292,8 +1292,8 @@ async fn test_trade_same_stacked_item_to_eachother() { async fn test_trade_stacked_when_already_have_partial_stack() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack = futures::future::join_all((0..3).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -1430,8 +1430,8 @@ async fn test_trade_stacked_when_already_have_partial_stack() { async fn test_trade_individual_for_stacked() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_inv = vec![ entity_gateway.create_item( @@ -1598,8 +1598,8 @@ async fn test_trade_individual_for_stacked() { async fn test_trade_multiple_individual() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_inv = vec![ entity_gateway.create_item( @@ -1854,8 +1854,8 @@ async fn test_trade_multiple_individual() { async fn test_trade_multiple_stacked() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack1 = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -2119,8 +2119,8 @@ async fn test_trade_multiple_stacked() { async fn test_trade_not_enough_inventory_space_individual() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_inv = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -2240,8 +2240,8 @@ async fn test_trade_not_enough_inventory_space_individual() { async fn test_trade_not_enough_inventory_space_stacked() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -2355,8 +2355,8 @@ async fn test_trade_not_enough_inventory_space_stacked() { async fn test_trade_stack_too_big() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack = futures::future::join_all((0..8).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -2469,8 +2469,8 @@ async fn test_trade_stack_too_big() { async fn test_trade_meseta() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; entity_gateway.set_character_meseta(&char1.id, Meseta(2323)).await.unwrap(); @@ -2548,8 +2548,8 @@ async fn test_trade_meseta() { async fn test_trade_too_much_meseta() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; entity_gateway.set_character_meseta(&char1.id, Meseta(4000)).await.unwrap(); entity_gateway.set_character_meseta(&char2.id, Meseta(999000)).await.unwrap(); @@ -2598,8 +2598,8 @@ async fn test_trade_too_much_meseta() { async fn test_trade_invalid_amount_of_meseta() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; entity_gateway.set_character_meseta(&char1.id, Meseta(4000)).await.unwrap(); entity_gateway.set_character_meseta(&char2.id, Meseta(999000)).await.unwrap(); @@ -2648,8 +2648,8 @@ async fn test_trade_invalid_amount_of_meseta() { async fn test_trade_meseta_request_and_items_dont_match() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; entity_gateway.set_character_meseta(&char1.id, Meseta(4000)).await.unwrap(); entity_gateway.set_character_meseta(&char2.id, Meseta(999000)).await.unwrap(); @@ -2698,8 +2698,8 @@ async fn test_trade_meseta_request_and_items_dont_match() { async fn test_player_declined_trade() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; @@ -2727,8 +2727,8 @@ async fn test_player_declined_trade() { async fn test_back_out_of_trade_last_minute() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( @@ -2791,8 +2791,8 @@ async fn test_back_out_of_trade_last_minute() { async fn test_valid_trade_when_both_inventories_are_full() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_inv = futures::future::join_all((0..30).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -2931,8 +2931,8 @@ async fn test_valid_trade_when_both_inventories_are_full() { async fn test_invalid_trade_when_both_inventories_are_full() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_inv = futures::future::join_all((0..30).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -3081,9 +3081,9 @@ async fn test_invalid_trade_when_both_inventories_are_full() { async fn test_client_tries_to_start_two_trades() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; - let (_user2, _char3) = new_user_character(&mut entity_gateway, "a3", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; + let (_user2, _char3) = new_user_character(&mut entity_gateway, "a3", "a").await; let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; @@ -3112,9 +3112,9 @@ async fn test_client_tries_to_start_two_trades() { async fn test_client_tries_trading_with_client_already_trading() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; - let (_user2, _char3) = new_user_character(&mut entity_gateway, "a3", "a", 1).await; + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; + let (_user2, _char3) = new_user_character(&mut entity_gateway, "a3", "a").await; let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; @@ -3149,8 +3149,8 @@ async fn test_client_tries_trading_with_client_already_trading() { async fn test_add_then_remove_individual_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_inv = Vec::new(); for _ in 0..2 { @@ -3260,8 +3260,8 @@ async fn test_add_then_remove_individual_item() { async fn test_add_then_remove_stacked_item() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack1 = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -3393,8 +3393,8 @@ async fn test_add_then_remove_stacked_item() { async fn test_add_then_remove_partial_stack() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack1 = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -3515,8 +3515,8 @@ async fn test_add_then_remove_partial_stack() { async fn test_add_then_remove_meseta() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; entity_gateway.set_character_meseta(&char1.id, Meseta(2323)).await.unwrap(); @@ -3599,8 +3599,8 @@ async fn test_add_then_remove_meseta() { async fn test_items_to_trade_data_does_not_match() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( @@ -3680,8 +3680,8 @@ async fn test_items_to_trade_data_does_not_match() { async fn test_items_to_trade_id_does_not_match() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( @@ -3749,8 +3749,8 @@ async fn test_items_to_trade_id_does_not_match() { async fn test_stack_is_same_amount_in_request_and_items_to_trade() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -3821,8 +3821,8 @@ async fn test_stack_is_same_amount_in_request_and_items_to_trade() { async fn test_stack_is_same_amount_in_request_and_items_to_trade2() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_stack = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); @@ -3893,8 +3893,8 @@ async fn test_stack_is_same_amount_in_request_and_items_to_trade2() { async fn test_items_to_trade_count_less_than() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_inv = vec![ entity_gateway.create_item( @@ -3993,8 +3993,8 @@ async fn test_items_to_trade_count_less_than() { async fn test_items_to_trade_count_greater_than() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; entity_gateway.set_character_meseta(&char1.id, Meseta(23)).await.unwrap(); @@ -4101,8 +4101,8 @@ async fn test_items_to_trade_count_greater_than() { async fn test_items_to_trade_count_mismatch_with_meseta() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let p1_inv = vec![ entity_gateway.create_item( @@ -4201,8 +4201,8 @@ async fn test_items_to_trade_count_mismatch_with_meseta() { async fn test_dropping_item_after_trade() { let mut entity_gateway = InMemoryGateway::default(); - let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; - let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( -- 2.36.0 From 9732c9276f7e15c1d509179dcf1a51b30ffe9bf4 Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 12 Nov 2023 00:47:59 -0700 Subject: [PATCH 49/58] this file has never been used why is it here --- src/login/models.rs | 92 --------------------------------------------- 1 file changed, 92 deletions(-) delete mode 100644 src/login/models.rs diff --git a/src/login/models.rs b/src/login/models.rs deleted file mode 100644 index c5fb059..0000000 --- a/src/login/models.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::time::SystemTime; -use std::io::Write; -//use diesel::sql_types::Timestamp; -use diesel::{Insertable, Queryable, Identifiable, Associations, AsExpression, FromSqlRow}; -//use bcrypt::{DEFAULT_COST, hash}; -use diesel::pg::Pg; -use diesel::sql_types; -use diesel::deserialize::{self, FromSql}; -use diesel::serialize::{self, ToSql, Output, IsNull}; -use diesel::backend::Backend; - -use libpso::character::settings; - -use elseware::schema::*; - -//const ELSEWHERE_COST: u32 = bcrypt::DEFAULT_COST; -const ELSEWHERE_COST: u32 = 5; - -#[derive(Debug, AsExpression, FromSqlRow)] -#[sql_type="sql_types::Binary"] -pub struct EUserSettings(pub settings::UserSettings); - -impl std::ops::Deref for EUserSettings { - type Target = settings::UserSettings; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -#[derive(Queryable, Identifiable, Debug)] -pub struct UserAccount { - pub id: i32, - pub username: String, - pub password: String, - pub guildcard: Option, - pub team_id: Option, - pub banned: bool, - pub muted_until: SystemTime, - pub created_at: SystemTime, -} - -#[derive(Insertable)] -#[table_name="user_accounts"] -pub struct NewUser { - username: String, - password: String, -} - -impl NewUser { - pub fn new(username: String, password: String) -> NewUser { - let crypt_password = bcrypt::hash(password, ELSEWHERE_COST).expect("could not hash password?"); - NewUser { - username: username, - password: crypt_password, - } - } -} - -#[derive(Queryable, Identifiable, Associations)] -#[belongs_to(UserAccount, foreign_key="user_id")] -#[table_name="user_settings"] -pub struct UserSettings { - pub id: i32, - pub user_id: i32, - //settings: Vec, - pub settings: EUserSettings, -} - -#[derive(Insertable, Debug)] -#[table_name="user_settings"] -pub struct NewUserSettings { - pub user_id: i32, - pub settings: EUserSettings, -} - -impl ToSql for EUserSettings { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - out.write_all(&self.0.as_bytes()[..]) - .map(|_| IsNull::No) - .map_err(|e| Box::new(e) as Box) - } -} - -impl FromSql for EUserSettings { - fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { - let bytes_vec: Vec = as FromSql>::from_sql(bytes)?; - let mut static_bytes = [0u8; 0x1160]; - static_bytes[..0x1160].clone_from_slice(&bytes_vec); - Ok(EUserSettings(settings::UserSettings::from_bytes(static_bytes))) - } -} -- 2.36.0 From c5dd7db248c9cb48dbac344f8e4a9025a61fe718 Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 12 Nov 2023 00:57:25 -0700 Subject: [PATCH 50/58] missed one --- tests/test_character.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_character.rs b/tests/test_character.rs index fb68d80..3a9cc64 100644 --- a/tests/test_character.rs +++ b/tests/test_character.rs @@ -33,7 +33,7 @@ async fn test_save_options() { async fn test_change_keyboard_mappings() { let mut entity_gateway = InMemoryGateway::default(); - let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 2).await; + let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; -- 2.36.0 From 1a140eea8f536a6ad8caa0543828081420a79449 Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 12 Nov 2023 16:33:27 -0700 Subject: [PATCH 51/58] clean up tests a bit by using itembuilder rather than using structs directly --- tests/common.rs | 265 ++++++++++++++- tests/test_bank.rs | 410 ++++++----------------- tests/test_item_actions.rs | 106 ++---- tests/test_item_id.rs | 74 ++-- tests/test_item_pickup.rs | 150 +++------ tests/test_item_use.rs | 128 ++----- tests/test_mags.rs | 54 +-- tests/test_shops.rs | 214 ++++-------- tests/test_trade.rs | 667 +++++++++---------------------------- 9 files changed, 744 insertions(+), 1324 deletions(-) diff --git a/tests/common.rs b/tests/common.rs index e2a3555..eb21187 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -161,9 +161,23 @@ pub async fn join_room(ship: &mut ShipServerState pub struct WeaponBuilder { weapon: item::weapon::WeaponType, grind: u8, + special: Option, + attributes: [Option; 3], + tekked: bool, } + impl WeaponBuilder { + fn new(weapon: item::weapon::WeaponType) -> WeaponBuilder { + WeaponBuilder { + weapon, + grind: 0, + special: None, + attributes: [None; 3], + tekked: true, + } + } + pub fn grind(self, grind: u8) -> WeaponBuilder { WeaponBuilder { grind, @@ -171,28 +185,267 @@ impl WeaponBuilder { } } + pub fn special(self, special: item::weapon::WeaponSpecial) -> WeaponBuilder { + WeaponBuilder { + special: Some(special), + ..self + } + } + + pub fn attr(mut self, attr: item::weapon::Attribute, value: i8) -> WeaponBuilder { + self.attributes + .iter_mut() + .find(|k| k.is_none()) + .map(|empty_attr| { + *empty_attr = Some(item::weapon::WeaponAttribute { + attr, + value, + }) + }); + + self + } + + pub fn untekked(self) -> WeaponBuilder { + WeaponBuilder { + tekked: false, + ..self + } + } + pub fn as_new(self) -> item::NewItemEntity { item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { weapon: self.weapon, grind: self.grind, - special: None, - attrs: [None, None, None], - tekked: true, + special: self.special, + attrs: self.attributes, + tekked: self.tekked, + } + ) + } + } +} + +pub struct ArmorBuilder { + armor: item::armor::ArmorType, + dfp: u8, + evp: u8, + slots: u8, +} + +impl ArmorBuilder { + pub fn new(armor: item::armor::ArmorType) -> ArmorBuilder { + ArmorBuilder { + armor: armor, + dfp: 0, + evp: 0, + slots: 0, + } + } + + pub fn slots(self, slots: u8) -> ArmorBuilder { + ArmorBuilder { + slots, + ..self + } + } + + pub fn dfp(self, dfp: u8) -> ArmorBuilder { + ArmorBuilder { + dfp, + ..self + } + } + + pub fn evp(self, evp: u8) -> ArmorBuilder { + ArmorBuilder { + evp, + ..self + } + } + + pub fn as_new(self) -> item::NewItemEntity { + item::NewItemEntity { + item: item::ItemDetail::Armor( + item::armor::Armor { + armor: self.armor, + dfp: self.dfp, + evp: self.evp, + slots: self.slots, + } + ) + } + } +} + +pub struct ShieldBuilder { + shield: item::shield::ShieldType, + dfp: u8, + evp: u8, +} + +impl ShieldBuilder { + pub fn new(shield: item::shield::ShieldType) -> ShieldBuilder { + ShieldBuilder { + shield: shield, + dfp: 0, + evp: 0, + } + } + + pub fn dfp(self, dfp: u8) -> ShieldBuilder { + ShieldBuilder { + dfp, + ..self + } + } + + pub fn evp(self, evp: u8) -> ShieldBuilder { + ShieldBuilder { + evp, + ..self + } + } + + pub fn as_new(self) -> item::NewItemEntity { + item::NewItemEntity { + item: item::ItemDetail::Shield( + item::shield::Shield { + shield: self.shield, + dfp: self.dfp, + evp: self.evp, + } + ) + } + } +} + + +pub struct UnitBuilder { + unit: item::unit::UnitType, + modifier: Option, +} + +impl UnitBuilder { + pub fn modifier(self, modifier: item::unit::UnitModifier) -> UnitBuilder { + UnitBuilder { + modifier: Some(modifier), + ..self + } + } + + pub fn as_new(self) -> item::NewItemEntity { + item::NewItemEntity { + item: item::ItemDetail::Unit( + item::unit::Unit { + unit: self.unit, + modifier: self.modifier, } ) } } } + +pub struct MagBuilder { +} + +impl MagBuilder { + pub fn as_new(self) -> item::NewItemEntity { + item::NewItemEntity { + item: item::ItemDetail::Mag( + item::mag::Mag::baby_mag(0) + ) + } + } +} + + + +pub struct ToolBuilder { + tool: item::tool::ToolType, +} + +impl ToolBuilder { + pub fn as_new(self) -> item::NewItemEntity { + item::NewItemEntity { + item: item::ItemDetail::Tool ( + item::tool::Tool { + tool: self.tool, + } + ), + } + } +} + +pub struct TechBuilder { + tech: item::tech::Technique, + level: u32, +} + + +impl TechBuilder { + pub fn level(self, level: u32) -> TechBuilder { + TechBuilder { + level, + ..self + } + } + + pub fn as_new(self) -> item::NewItemEntity { + item::NewItemEntity { + item: item::ItemDetail::TechniqueDisk ( + item::tech::TechniqueDisk { + tech: self.tech, + level: self.level, + } + ) + } + } +} + + pub struct ItemBuilder; impl ItemBuilder { pub fn weapon(weapon: item::weapon::WeaponType) -> WeaponBuilder { - WeaponBuilder { - weapon, - grind: 0, + WeaponBuilder::new(weapon) + } + + pub fn armor(armor: item::armor::ArmorType) -> ArmorBuilder { + ArmorBuilder::new(armor) + } + + pub fn shield(shield: item::shield::ShieldType) -> ShieldBuilder { + ShieldBuilder::new(shield) + } + + pub fn unit(unit: item::unit::UnitType) -> UnitBuilder { + UnitBuilder { + unit: unit, + modifier: None, + } + } + + pub fn baby_mag() -> MagBuilder { + MagBuilder { } } + + pub fn tool(tool: item::tool::ToolType) -> ToolBuilder { + ToolBuilder { + tool: tool, + } + } + + pub fn tech(tech: item::tech::Technique) -> TechBuilder { + TechBuilder { + tech: tech, + level: 0, + } + } + + } diff --git a/tests/test_bank.rs b/tests/test_bank.rs index a3ad3e8..9211f97 100644 --- a/tests/test_bank.rs +++ b/tests/test_bank.rs @@ -20,17 +20,9 @@ async fn test_bank_items_sent_in_character_login() { let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let item = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .as_new() + ).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![item]), &item::BankIdentifier::Character).await.unwrap(); @@ -55,17 +47,9 @@ async fn test_request_bank_items() { let mut bank = Vec::new(); for _ in 0..3 { bank.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap(); @@ -101,13 +85,9 @@ async fn test_request_stacked_bank_items() { let mut monomates = Vec::new(); for _ in 0..3usize { monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool ( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap(); @@ -140,37 +120,17 @@ async fn test_request_bank_items_sorted() { let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let item1 = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .as_new() + ).await.unwrap(); let monomate = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool ( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap(); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap(); let item2 = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Calibur, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(); + ItemBuilder::weapon(item::weapon::WeaponType::Calibur) + .as_new() + ).await.unwrap(); let bank = vec![item::BankItemEntity::Individual(item1), vec![monomate].into(), item2.into()]; entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap(); @@ -204,29 +164,13 @@ async fn test_deposit_individual_item() { let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let item0 = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(); + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap(); let item1 = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(); + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap(); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![item0, item1])).await.unwrap(); @@ -283,13 +227,9 @@ async fn test_deposit_stacked_item() { let mut monomates = Vec::new(); for _ in 0..3usize { monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); @@ -342,13 +282,9 @@ async fn test_deposit_partial_stacked_item() { let mut monomates = Vec::new(); for _ in 0..3usize { monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); @@ -411,22 +347,14 @@ async fn test_deposit_stacked_item_with_stack_already_in_bank() { let mut inventory_monomates = Vec::new(); for _ in 0..2usize { inventory_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); bank_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); @@ -479,25 +407,17 @@ async fn test_deposit_stacked_item_with_full_stack_in_bank() { let mut inventory_monomates = Vec::new(); for _ in 0..2usize { inventory_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } let mut bank_monomates = Vec::new(); for _ in 0..10 { bank_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); @@ -548,32 +468,16 @@ async fn test_deposit_individual_item_in_full_bank() { let mut inventory = Vec::new(); inventory.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .as_new() + ).await.unwrap()); let mut bank = Vec::new(); for _ in 0..200usize { bank.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap(); @@ -621,29 +525,17 @@ async fn test_deposit_stacked_item_in_full_bank() { let mut monomates = Vec::new(); for _ in 0..2usize { monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } let mut full_bank = Vec::new(); for _ in 0..200usize { full_bank.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); @@ -692,41 +584,25 @@ async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() { let mut monomates = Vec::new(); for _ in 0..2usize { monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } let mut bank_monomates = Vec::new(); for _ in 0..2usize { bank_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } let mut almost_full_bank: Vec = Vec::new(); for _ in 0..199usize { almost_full_bank.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap().into()); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .as_new() + ).await.unwrap().into()); } almost_full_bank.push(bank_monomates.into()); @@ -882,17 +758,9 @@ async fn test_withdraw_individual_item() { let mut bank = Vec::new(); bank.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap()); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap(); @@ -943,13 +811,9 @@ async fn test_withdraw_stacked_item() { let mut monomates = Vec::new(); for _ in 0..3usize { monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap(); @@ -1001,13 +865,9 @@ async fn test_withdraw_partial_stacked_item() { let mut monomates = Vec::new(); for _ in 0..3usize { monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap(); @@ -1066,22 +926,14 @@ async fn test_withdraw_stacked_item_with_stack_already_in_inventory() { let mut bank_monomates = Vec::new(); for _ in 0..2usize { inventory_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); bank_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); @@ -1136,25 +988,17 @@ async fn test_withdraw_stacked_item_with_full_stack_in_inventory() { let mut bank_monomates = Vec::new(); for _ in 0..2usize { bank_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } let mut inventory_monomates = Vec::new(); for _ in 0..10usize { inventory_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); @@ -1205,32 +1049,16 @@ async fn test_withdraw_individual_item_in_full_inventory() { let mut bank = Vec::new(); bank.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .as_new() + ).await.unwrap()); let mut inventory = Vec::new(); for _ in 0..30usize { inventory.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap(); @@ -1274,29 +1102,17 @@ async fn test_withdraw_stacked_item_in_full_inventory() { let mut monomates = Vec::new(); for _ in 0..2usize { monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } let mut inventory = Vec::new(); for _ in 0..30usize { inventory.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap(); @@ -1346,42 +1162,26 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() { let mut bank_item = Vec::new(); for _ in 0..2usize { bank_item.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_item]), &item::BankIdentifier::Character).await.unwrap(); let mut items = Vec::new(); for _i in 0..29usize { items.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap().into()); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .as_new() + ).await.unwrap().into()); } let mut item29 = Vec::new(); for _ in 0..2usize { item29.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } items.push(item::InventoryItemEntity::Stacked(item29)); diff --git a/tests/test_item_actions.rs b/tests/test_item_actions.rs index 2072403..beef459 100644 --- a/tests/test_item_actions.rs +++ b/tests/test_item_actions.rs @@ -18,33 +18,21 @@ async fn test_equip_unit_from_equip_menu() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Armor( - item::armor::Armor{ - armor: item::armor::ArmorType::Frame, - dfp: 0, - evp: 0, - slots: 4, - }), - }).await.unwrap()); + ItemBuilder::armor(item::armor::ArmorType::Frame) + .slots(4) + .as_new() + ).await.unwrap()); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Unit( - item::unit::Unit{ - unit: item::unit::UnitType::KnightPower, - modifier: None, - }), - }).await.unwrap()); + ItemBuilder::unit(item::unit::UnitType::KnightPower) + .as_new() + ).await.unwrap()); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Unit( - item::unit::Unit{ - unit: item::unit::UnitType::KnightPower, - modifier: Some(item::unit::UnitModifier::Plus), - }), - }).await.unwrap()); + ItemBuilder::unit(item::unit::UnitType::KnightPower) + .modifier(item::unit::UnitModifier::Plus) + .as_new() + ).await.unwrap()); let equipped = item::EquippedEntity { weapon: None, @@ -93,33 +81,21 @@ async fn test_unequip_armor_with_units() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Armor( - item::armor::Armor{ - armor: item::armor::ArmorType::Frame, - dfp: 0, - evp: 0, - slots: 4, - }), - }).await.unwrap()); + ItemBuilder::armor(item::armor::ArmorType::Frame) + .slots(4) + .as_new() + ).await.unwrap()); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Unit( - item::unit::Unit{ - unit: item::unit::UnitType::KnightPower, - modifier: None, - }), - }).await.unwrap()); + ItemBuilder::unit(item::unit::UnitType::KnightPower) + .as_new() + ).await.unwrap()); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Unit( - item::unit::Unit{ - unit: item::unit::UnitType::KnightPower, - modifier: Some(item::unit::UnitModifier::Plus), - }), - }).await.unwrap()); + ItemBuilder::unit(item::unit::UnitType::KnightPower) + .modifier(item::unit::UnitModifier::Plus) + .as_new() + ).await.unwrap()); let equipped = item::EquippedEntity { weapon: None, @@ -159,33 +135,21 @@ async fn test_sort_items() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Armor( - item::armor::Armor{ - armor: item::armor::ArmorType::Frame, - dfp: 0, - evp: 0, - slots: 4, - }), - }).await.unwrap()); + ItemBuilder::armor(item::armor::ArmorType::Frame) + .slots(4) + .as_new() + ).await.unwrap()); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Unit( - item::unit::Unit{ - unit: item::unit::UnitType::KnightPower, - modifier: None, - }), - }).await.unwrap()); + ItemBuilder::unit(item::unit::UnitType::KnightPower) + .as_new() + ).await.unwrap()); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Unit( - item::unit::Unit{ - unit: item::unit::UnitType::KnightPower, - modifier: Some(item::unit::UnitModifier::Plus), - }), - }).await.unwrap()); + ItemBuilder::unit(item::unit::UnitType::KnightPower) + .modifier(item::unit::UnitModifier::Plus) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -210,8 +174,8 @@ async fn test_sort_items() { ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::SortItems(SortItems { client: 255, target: 255, - item_ids: [0x10001u32, 0x10002, 0x10000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + item_ids: [0x10001u32, 0x10002, 0x10000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF], })))).await.unwrap(); diff --git a/tests/test_item_id.rs b/tests/test_item_id.rs index d887af4..01ec5d2 100644 --- a/tests/test_item_id.rs +++ b/tests/test_item_id.rs @@ -22,13 +22,9 @@ async fn test_use_monomate_after_leaving_and_rejoining_room() { let mut item = Vec::new(); for _ in 0..2usize { item.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: tool - } - ), - }).await.unwrap()); + ItemBuilder::tool(tool) + .as_new() + ).await.unwrap()); } p1_items.push(item::InventoryItemEntity::Stacked(item)); } @@ -40,13 +36,9 @@ async fn test_use_monomate_after_leaving_and_rejoining_room() { let mut item = Vec::new(); for _ in 0..2usize { item.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: tool - } - ), - }).await.unwrap()); + ItemBuilder::tool(tool) + .as_new() + ).await.unwrap()); } p2_items.push(item::InventoryItemEntity::Stacked(item)); } @@ -116,13 +108,9 @@ async fn test_using_some_monomates_after_a_convoluted_series_of_leaves_and_joins let mut item = Vec::new(); for _ in 0..2usize { item.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: tool - } - ), - }).await.unwrap()); + ItemBuilder::tool(tool) + .as_new() + ).await.unwrap()); } p1_items.push(item::InventoryItemEntity::Stacked(item)); } @@ -133,13 +121,9 @@ async fn test_using_some_monomates_after_a_convoluted_series_of_leaves_and_joins let mut item = Vec::new(); for _ in 0..6usize { item.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: tool - } - ), - }).await.unwrap()); + ItemBuilder::tool(tool) + .as_new() + ).await.unwrap()); } p2_items.push(item::InventoryItemEntity::Stacked(item)); } @@ -150,17 +134,9 @@ async fn test_using_some_monomates_after_a_convoluted_series_of_leaves_and_joins p3_items.push( item::InventoryItemEntity::Individual( entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap() + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap() )); } entity_gateway.set_character_inventory(&char3.id, &item::InventoryEntity::new(p3_items)).await.unwrap(); @@ -301,13 +277,9 @@ async fn test_depositing_a_full_stack_then_withdrawing_part() { let mut item = Vec::new(); for _ in 0..5usize { item.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: tool - } - ), - }).await.unwrap()); + ItemBuilder::tool(tool) + .as_new() + ).await.unwrap()); } p1_items.push(item::InventoryItemEntity::Stacked(item)); } @@ -316,13 +288,9 @@ async fn test_depositing_a_full_stack_then_withdrawing_part() { let mut monomates = Vec::new(); for _ in 0..3usize { monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap(); diff --git a/tests/test_item_pickup.rs b/tests/test_item_pickup.rs index 7788ffb..82dd777 100644 --- a/tests/test_item_pickup.rs +++ b/tests/test_item_pickup.rs @@ -19,17 +19,9 @@ async fn test_pick_up_individual_item() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -88,26 +80,18 @@ async fn test_pick_up_item_stack_of_items_already_in_inventory() { let mut p1_monomate = Vec::new(); p1_monomate.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); let mut p2_items = Vec::new(); for (_slot, tool) in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter().enumerate() { let mut item = Vec::new(); for _ in 0..5usize { item.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: tool - } - ), - }).await.unwrap()); + ItemBuilder::tool(tool) + .as_new() + ).await.unwrap()); } p2_items.push(item); } @@ -162,13 +146,9 @@ async fn test_pick_up_item_stack_of_items_not_already_held() { let mut p2_monomate = Vec::new(); p2_monomate.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomate])).await.unwrap(); @@ -220,17 +200,9 @@ async fn test_pick_up_meseta_when_inventory_full() { let mut p1_items = Vec::new(); for _ in 0..30usize { p1_items.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); @@ -291,37 +263,21 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { let mut p1_inv = Vec::new(); for _slot in 0..29usize { p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap().into()); + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap().into()); } p1_inv.push(item::InventoryItemEntity::Stacked(vec![entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()])); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()])); let mut p2_monomates = Vec::new(); p2_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomates])).await.unwrap(); @@ -372,32 +328,16 @@ async fn test_can_not_pick_up_item_when_inventory_full() { let mut p1_inv = Vec::new(); for _slot in 0..30usize { p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap()); } let mut p2_inv = Vec::new(); p2_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); @@ -498,25 +438,17 @@ async fn test_pick_up_stack_that_would_exceed_stack_limit() { let mut p1_monomates = Vec::new(); for _ in 0..6usize { p1_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } let mut p2_monomates = Vec::new(); for _ in 0..6usize { p2_monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_monomates])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomates])).await.unwrap(); @@ -675,13 +607,9 @@ async fn test_player_drops_partial_stack_and_other_player_picks_it_up() { let mut monomates = Vec::new(); for _ in 0..5usize { monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); diff --git a/tests/test_item_use.rs b/tests/test_item_use.rs index a117da7..d4117f7 100644 --- a/tests/test_item_use.rs +++ b/tests/test_item_use.rs @@ -23,13 +23,9 @@ async fn test_use_monomate() { let mut item = Vec::new(); for _ in 0..2usize { item.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: tool - } - ), - }).await.unwrap()); + ItemBuilder::tool(tool) + .as_new() + ).await.unwrap()); } p1_items.push(item::InventoryItemEntity::Stacked(item)); } @@ -68,13 +64,9 @@ async fn test_use_monomate_twice() { let mut item = Vec::new(); for _ in 0..3usize { item.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: tool - } - ), - }).await.unwrap()); + ItemBuilder::tool(tool) + .as_new() + ).await.unwrap()); } p1_items.push(item::InventoryItemEntity::Stacked(item)); } @@ -116,13 +108,9 @@ async fn test_use_last_monomate() { let mut p1_inv = Vec::new(); for tool in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter() { p1_inv.push(item::InventoryItemEntity::Stacked(vec![entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: tool - } - ), - }).await.unwrap()])); + ItemBuilder::tool(tool) + .as_new() + ).await.unwrap()])); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -155,13 +143,9 @@ async fn test_use_nonstackable_tool() { let mut p1_items = Vec::new(); p1_items.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::HuntersReport, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::HuntersReport) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); @@ -191,13 +175,9 @@ async fn test_use_materials() { let mut item = Vec::new(); for _ in 0..5usize { item.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: tool - } - ), - }).await.unwrap()); + ItemBuilder::tool(tool) + .as_new() + ).await.unwrap()); } p1_inv.push(item::InventoryItemEntity::Stacked(item)); } @@ -250,20 +230,13 @@ async fn test_jackolantern() { item::InventoryItemEntity::Stacked( vec![ entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::JackOLantern, - } - ), - }).await.unwrap(), - entity_gateway.create_item(item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::JackOLantern, - } - ), - }).await.unwrap(), + ItemBuilder::tool(item::tool::ToolType::JackOLantern) + .as_new() + ).await.unwrap(), + entity_gateway.create_item( + ItemBuilder::tool(item::tool::ToolType::JackOLantern) + .as_new() + ).await.unwrap(), ])]; entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -301,34 +274,19 @@ async fn test_use_barta_1() { let inv = vec![ entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::TechniqueDisk( - item::tech::TechniqueDisk { - tech: item::tech::Technique::Foie, - level: 3, - } - ) - } + ItemBuilder::tech(item::tech::Technique::Foie) + .level(3) + .as_new() ).await.unwrap(), entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::TechniqueDisk( - item::tech::TechniqueDisk { - tech: item::tech::Technique::Barta, - level: 4, - } - ) - } + ItemBuilder::tech(item::tech::Technique::Barta) + .level(4) + .as_new() ).await.unwrap(), entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::TechniqueDisk( - item::tech::TechniqueDisk { - tech: item::tech::Technique::Zonde, - level: 5, - } - ) - } + ItemBuilder::tech(item::tech::Technique::Zonde) + .level(5) + .as_new() ).await.unwrap() ]; @@ -368,28 +326,16 @@ async fn test_use_monogrinder() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let saber = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(); + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap(); let mut grinders = Vec::new(); for _ in 0..3usize { grinders.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monogrinder, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monogrinder) + .as_new() + ).await.unwrap()); } let equipped = item::EquippedEntity { diff --git a/tests/test_mags.rs b/tests/test_mags.rs index a4ee763..d55a269 100644 --- a/tests/test_mags.rs +++ b/tests/test_mags.rs @@ -18,22 +18,16 @@ async fn test_mag_feed() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mag = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Mag( - item::mag::Mag::baby_mag(0) - ), - }).await.unwrap(); + ItemBuilder::baby_mag() + .as_new() + ).await.unwrap(); let mut monomates = Vec::new(); for _ in 0..7usize { monomates.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap()); } let equipped = item::EquippedEntity { @@ -95,11 +89,9 @@ async fn test_mag_change_owner() { entity_gateway.save_character(&char2).await.unwrap(); let mag = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Mag( - item::mag::Mag::baby_mag(0) - ), - }).await.unwrap(); + ItemBuilder::baby_mag() + .as_new() + ).await.unwrap(); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![mag])).await.unwrap(); @@ -151,31 +143,21 @@ async fn test_mag_cell() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mag = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Mag( - item::mag::Mag::baby_mag(0) - ), - }).await.unwrap(); + ItemBuilder::baby_mag() + .as_new() + ).await.unwrap(); for _ in 0..1000usize { let fed_tool = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool ( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ), - }).await.unwrap(); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap(); entity_gateway.feed_mag(&mag.id, &fed_tool.id).await.unwrap(); } let mag_cell = entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::CellOfMag502, - } - ), - }).await.unwrap(); + ItemBuilder::tool(item::tool::ToolType::CellOfMag502) + .as_new() + ).await.unwrap(); let equipped = item::EquippedEntity { weapon: None, diff --git a/tests/test_shops.rs b/tests/test_shops.rs index 4855db4..3e2dc02 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -265,19 +265,14 @@ async fn test_player_sells_3_attr_weapon_to_shop() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 5, - special: Some(item::weapon::WeaponSpecial::Charge), - attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}), - Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}), - Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .grind(5) + .special(item::weapon::WeaponSpecial::Charge) + .attr(item::weapon::Attribute::Hit, 100) + .attr(item::weapon::Attribute::Dark, 100) + .attr(item::weapon::Attribute::Native, 100) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -351,13 +346,9 @@ async fn test_other_clients_see_stacked_purchase() { entity_gateway.save_character(&char1).await.unwrap(); entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap(); entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate - } - ), - }).await.unwrap(); + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await.unwrap(); let mut ship = standard_ship_buildable(entity_gateway.clone()) .item_shops(StandardItemShops::default()) @@ -622,19 +613,15 @@ async fn test_player_sells_untekked_weapon() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 5, - special: Some(item::weapon::WeaponSpecial::Charge), - attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}), - Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}), - Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),], - tekked: false, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Vulcan) + .untekked() + .grind(5) + .special(item::weapon::WeaponSpecial::Charge) + .attr(item::weapon::Attribute::Hit, 100) + .attr(item::weapon::Attribute::Dark, 100) + .attr(item::weapon::Attribute::Native, 100) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -664,19 +651,13 @@ async fn test_player_sells_rare_item() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::DarkFlow, - grind: 5, - special: None, - attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}), - Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}), - Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::DarkFlow) + .grind(5) + .attr(item::weapon::Attribute::Hit, 100) + .attr(item::weapon::Attribute::Dark, 100) + .attr(item::weapon::Attribute::Native, 100) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -708,13 +689,9 @@ async fn test_player_sells_partial_photon_drop_stack() { let mut photon_drops = Vec::new(); for _ in 0..7usize { photon_drops.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::PhotonDrop, - } - ), - }).await.unwrap()); + ItemBuilder::tool(item::tool::ToolType::PhotonDrop) + .as_new() + ).await.unwrap()); } p1_inv.push(item::InventoryItemEntity::Stacked(photon_drops)); @@ -747,16 +724,9 @@ async fn test_player_sells_basic_frame() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Armor( - item::armor::Armor { - armor: item::armor::ArmorType::Frame, - dfp: 0, - evp: 0, - slots: 0, - } - ), - }).await.unwrap()); + ItemBuilder::armor(item::armor::ArmorType::Frame) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -786,16 +756,12 @@ async fn test_player_sells_max_frame() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Armor( - item::armor::Armor { - armor: item::armor::ArmorType::Frame, - dfp: 2, - evp: 2, - slots: 4, - } - ), - }).await.unwrap()); + ItemBuilder::armor(item::armor::ArmorType::Frame) + .dfp(2) + .evp(2) + .slots(4) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -825,15 +791,9 @@ async fn test_player_sells_basic_barrier() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Shield( - item::shield::Shield { - shield: item::shield::ShieldType::Barrier, - dfp: 0, - evp: 0, - } - ), - }).await.unwrap()); + ItemBuilder::shield(item::shield::ShieldType::Barrier) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -863,15 +823,11 @@ async fn test_player_sells_max_barrier() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Shield( - item::shield::Shield { - shield: item::shield::ShieldType::Barrier, - dfp: 5, - evp: 5, - } - ), - }).await.unwrap()); + ItemBuilder::shield(item::shield::ShieldType::Barrier) + .dfp(5) + .evp(5) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -901,14 +857,10 @@ async fn test_player_sells_1_star_minusminus_unit() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Unit( - item::unit::Unit { - unit: item::unit::UnitType::PriestMind, - modifier: Some(item::unit::UnitModifier::MinusMinus), - } - ), - }).await.unwrap()); + ItemBuilder::unit(item::unit::UnitType::PriestMind) + .modifier(item::unit::UnitModifier::MinusMinus) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -938,14 +890,10 @@ async fn test_player_sells_5_star_plusplus_unit() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Unit( - item::unit::Unit { - unit: item::unit::UnitType::GeneralHp, - modifier: Some(item::unit::UnitModifier::PlusPlus), - } - ), - }).await.unwrap()); + ItemBuilder::unit(item::unit::UnitType::GeneralHp) + .modifier(item::unit::UnitModifier::PlusPlus) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -975,16 +923,12 @@ async fn test_player_sells_rare_frame() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Armor( - item::armor::Armor { - armor: item::armor::ArmorType::StinkFrame, - dfp: 10, - evp: 20, - slots: 3, - } - ), - }).await.unwrap()); + ItemBuilder::armor(item::armor::ArmorType::StinkFrame) + .dfp(10) + .evp(20) + .slots(3) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -1014,15 +958,11 @@ async fn test_player_sells_rare_barrier() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Shield( - item::shield::Shield { - shield: item::shield::ShieldType::RedRing, - dfp: 10, - evp: 20, - } - ), - }).await.unwrap()); + ItemBuilder::shield(item::shield::ShieldType::RedRing) + .dfp(10) + .evp(20) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -1052,14 +992,9 @@ async fn test_player_sells_rare_unit() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Unit( - item::unit::Unit { - unit: item::unit::UnitType::V101, - modifier: None, - } - ), - }).await.unwrap()); + ItemBuilder::unit(item::unit::UnitType::V101) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -1090,14 +1025,9 @@ async fn test_player_cant_sell_if_meseta_would_go_over_max() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Unit( - item::unit::Unit { - unit: item::unit::UnitType::V101, - modifier: None, - } - ), - }).await.unwrap()); + ItemBuilder::unit(item::unit::UnitType::V101) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); diff --git a/tests/test_trade.rs b/tests/test_trade.rs index d35d31b..93f1463 100644 --- a/tests/test_trade.rs +++ b/tests/test_trade.rs @@ -118,17 +118,9 @@ async fn test_trade_one_individual_item() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -217,17 +209,9 @@ async fn test_trade_player2_to_player1() { let mut p2_inv = Vec::new(); p2_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); @@ -316,17 +300,9 @@ async fn test_reverse_trade_ack_order() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -417,13 +393,9 @@ async fn test_trade_one_stacked_item() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -519,13 +491,9 @@ async fn test_trade_partial_stacked_item() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -622,30 +590,14 @@ async fn test_trade_individual_both() { let p1_inv = vec![ entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()]; + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap()]; let p2_inv = vec![ entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()]; + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap()]; entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); @@ -787,13 +739,9 @@ async fn test_trade_stacked_both() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -804,13 +752,9 @@ async fn test_trade_stacked_both() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monofluid, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monofluid) + .as_new() + ).await }})) .await .into_iter() @@ -955,13 +899,9 @@ async fn test_trade_partial_stack_both() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -972,13 +912,9 @@ async fn test_trade_partial_stack_both() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monofluid, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monofluid) + .as_new() + ).await }})) .await .into_iter() @@ -1129,13 +1065,9 @@ async fn test_trade_same_stacked_item_to_eachother() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -1146,13 +1078,9 @@ async fn test_trade_same_stacked_item_to_eachother() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -1299,13 +1227,9 @@ async fn test_trade_stacked_when_already_have_partial_stack() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -1316,13 +1240,9 @@ async fn test_trade_stacked_when_already_have_partial_stack() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -1435,29 +1355,17 @@ async fn test_trade_individual_for_stacked() { let p1_inv = vec![ entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()]; + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap()]; let p2_stack = futures::future::join_all((0..2).map(|_| { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -1603,55 +1511,23 @@ async fn test_trade_multiple_individual() { let p1_inv = vec![ entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap(), entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Buster, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Buster) + .as_new() + ).await.unwrap(), ]; let p2_inv = vec![ entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap(), entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Autogun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Autogun) + .as_new() + ).await.unwrap(), ]; entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -1861,13 +1737,9 @@ async fn test_trade_multiple_stacked() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -1877,13 +1749,9 @@ async fn test_trade_multiple_stacked() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Dimate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Dimate) + .as_new() + ).await }})) .await .into_iter() @@ -1894,13 +1762,9 @@ async fn test_trade_multiple_stacked() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monofluid, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monofluid) + .as_new() + ).await }})) .await .into_iter() @@ -1910,13 +1774,9 @@ async fn test_trade_multiple_stacked() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Difluid, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Difluid) + .as_new() + ).await }})) .await .into_iter() @@ -2126,17 +1986,8 @@ async fn test_trade_not_enough_inventory_space_individual() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - } + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() ).await }})) .await @@ -2148,17 +1999,8 @@ async fn test_trade_not_enough_inventory_space_individual() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - } + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() ).await }})) .await @@ -2247,13 +2089,9 @@ async fn test_trade_not_enough_inventory_space_stacked() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -2264,17 +2102,8 @@ async fn test_trade_not_enough_inventory_space_stacked() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - } + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() ).await }})) .await @@ -2362,13 +2191,9 @@ async fn test_trade_stack_too_big() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -2379,13 +2204,9 @@ async fn test_trade_stack_too_big() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -2732,17 +2553,9 @@ async fn test_back_out_of_trade_last_minute() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -2798,17 +2611,8 @@ async fn test_valid_trade_when_both_inventories_are_full() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - } + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() ).await }})) .await @@ -2820,17 +2624,8 @@ async fn test_valid_trade_when_both_inventories_are_full() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - } + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() ).await }})) .await @@ -2938,17 +2733,8 @@ async fn test_invalid_trade_when_both_inventories_are_full() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - } + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() ).await }})) .await @@ -2960,17 +2746,8 @@ async fn test_invalid_trade_when_both_inventories_are_full() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - } + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() ).await }})) .await @@ -3155,17 +2932,9 @@ async fn test_add_then_remove_individual_item() { let mut p1_inv = Vec::new(); for _ in 0..2 { p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap()); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -3267,13 +3036,9 @@ async fn test_add_then_remove_stacked_item() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -3284,13 +3049,9 @@ async fn test_add_then_remove_stacked_item() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monofluid, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monofluid) + .as_new() + ).await }})) .await .into_iter() @@ -3400,13 +3161,9 @@ async fn test_add_then_remove_partial_stack() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -3417,13 +3174,9 @@ async fn test_add_then_remove_partial_stack() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monofluid, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monofluid) + .as_new() + ).await }})) .await .into_iter() @@ -3604,17 +3357,9 @@ async fn test_items_to_trade_data_does_not_match() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -3685,17 +3430,9 @@ async fn test_items_to_trade_id_does_not_match() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -3756,13 +3493,9 @@ async fn test_stack_is_same_amount_in_request_and_items_to_trade() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -3828,13 +3561,9 @@ async fn test_stack_is_same_amount_in_request_and_items_to_trade2() { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, - } - ) - }).await + ItemBuilder::tool(item::tool::ToolType::Monomate) + .as_new() + ).await }})) .await .into_iter() @@ -3898,41 +3627,17 @@ async fn test_items_to_trade_count_less_than() { let p1_inv = vec![ entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap(), entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Brand, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Brand) + .as_new() + ).await.unwrap(), entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Buster, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Buster) + .as_new() + ).await.unwrap(), ]; entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -4000,41 +3705,17 @@ async fn test_items_to_trade_count_greater_than() { let p1_inv = vec![ entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap(), entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Brand, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Brand) + .as_new() + ).await.unwrap(), entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Buster, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Buster) + .as_new() + ).await.unwrap(), ]; entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -4106,41 +3787,17 @@ async fn test_items_to_trade_count_mismatch_with_meseta() { let p1_inv = vec![ entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Saber, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Saber) + .as_new() + ).await.unwrap(), entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Brand, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Brand) + .as_new() + ).await.unwrap(), entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Buster, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap(), + ItemBuilder::weapon(item::weapon::WeaponType::Buster) + .as_new() + ).await.unwrap(), ]; entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); @@ -4206,17 +3863,9 @@ async fn test_dropping_item_after_trade() { let mut p1_inv = Vec::new(); p1_inv.push(entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - } - ), - }).await.unwrap()); + ItemBuilder::weapon(item::weapon::WeaponType::Handgun) + .as_new() + ).await.unwrap()); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); -- 2.36.0 From 4631ef325429234b3d6e38273cfa6bcf1cf93b61 Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 12 Nov 2023 18:57:46 -0700 Subject: [PATCH 52/58] don't need these deps here --- Cargo.toml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5737f97..ee03ec9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,24 +83,16 @@ room = { workspace = true } libpso = { workspace = true } -ages-prs = { workspace = true } anyhow = { workspace = true } -async-recursion = { workspace = true } async-std = { workspace = true } async-trait = { workspace = true } bcrypt = { workspace = true } -byteorder = { workspace = true } chrono = { workspace = true } crc = { workspace = true } -derive_more = { workspace = true } -enum-utils = { workspace = true } fern = { workspace = true } futures = { workspace = true } log = { workspace = true } rand = { workspace = true } -rand_chacha = { workspace = true } ron = { workspace = true } serde = { workspace = true } -serde_json = { workspace = true } -toml = { workspace = true } thiserror = { workspace = true } \ No newline at end of file -- 2.36.0 From 8ac5ad88a5e127c19b93b7775f6f67da346ef7ec Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 12 Nov 2023 19:16:55 -0700 Subject: [PATCH 53/58] move patch_server to own crate --- Cargo.toml | 3 +++ patch_server/Cargo.toml | 15 +++++++++++++++ src/patch/mod.rs => patch_server/src/lib.rs | 0 src/bin/main.rs | 2 +- src/bin/patch.rs | 2 +- src/lib.rs | 2 +- 6 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 patch_server/Cargo.toml rename src/patch/mod.rs => patch_server/src/lib.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index ee03ec9..a1eba71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ members = [ "shops", "stats", "trade", + "patch_server", ] [workspace.dependencies] @@ -35,6 +36,7 @@ client = { path = "./client" } drops = { path = "./drops" } trade = { path = "./trade" } room = { path = "./room" } +patch_server = { path = "./patch_server" } libpso = { git = "http://git.sharnoth.com/jake/libpso" } @@ -80,6 +82,7 @@ client = { workspace = true } drops = { workspace = true } trade = { workspace = true } room = { workspace = true } +patch_server = { workspace = true } libpso = { workspace = true } diff --git a/patch_server/Cargo.toml b/patch_server/Cargo.toml new file mode 100644 index 0000000..f528b04 --- /dev/null +++ b/patch_server/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "patch_server" +version = "0.1.0" +edition = "2021" + +[dependencies] +networking = { workspace = true } + +libpso = { workspace = true } + +async-trait = { workspace = true } +rand = { workspace = true } +crc = { workspace = true } +ron = { workspace = true } +serde = { workspace = true } diff --git a/src/patch/mod.rs b/patch_server/src/lib.rs similarity index 100% rename from src/patch/mod.rs rename to patch_server/src/lib.rs diff --git a/src/bin/main.rs b/src/bin/main.rs index e50db30..a61bf7b 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -4,7 +4,7 @@ use log::{info}; use networking::interserver::AuthToken; use elseware::login::login::LoginServerState; use elseware::login::character::CharacterServerState; -use elseware::patch::{PatchServerState, generate_patch_tree, load_config, load_motd}; +use patch_server::{PatchServerState, generate_patch_tree, load_config, load_motd}; use elseware::ship::ship::ShipServerStateBuilder; use maps::Holiday; diff --git a/src/bin/patch.rs b/src/bin/patch.rs index a9fb839..c38f025 100644 --- a/src/bin/patch.rs +++ b/src/bin/patch.rs @@ -1,4 +1,4 @@ -use elseware::patch::{PatchServerState, generate_patch_tree, load_config_env, load_motd}; +use patch_server::{PatchServerState, generate_patch_tree, load_config_env, load_motd}; use log::info; fn main() { diff --git a/src/lib.rs b/src/lib.rs index f194399..5436b77 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,6 @@ extern crate test; //pub mod common; //pub mod entity; -pub mod patch; +//pub mod patch; pub mod login; pub mod ship; -- 2.36.0 From 0fed0da24bb8b37a7ee1d8bd2e22af154726a522 Mon Sep 17 00:00:00 2001 From: jake Date: Mon, 13 Nov 2023 00:13:37 -0700 Subject: [PATCH 54/58] login_server crate --- Cargo.toml | 3 +++ login_server/Cargo.toml | 21 ++++++++++++++++++++ {src/login => login_server/src}/character.rs | 2 +- login_server/src/lib.rs | 2 ++ {src/login => login_server/src}/login.rs | 12 ++--------- src/bin/login.rs | 10 +++++----- src/bin/main.rs | 16 +++++++-------- src/bin/ship.rs | 2 +- src/lib.rs | 2 +- src/login/mod.rs | 3 --- src/ship/packet/handler/auth.rs | 2 +- 11 files changed, 45 insertions(+), 30 deletions(-) create mode 100644 login_server/Cargo.toml rename {src/login => login_server/src}/character.rs (99%) create mode 100644 login_server/src/lib.rs rename {src/login => login_server/src}/login.rs (98%) delete mode 100644 src/login/mod.rs diff --git a/Cargo.toml b/Cargo.toml index a1eba71..19347e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ members = [ "stats", "trade", "patch_server", + "login_server", ] [workspace.dependencies] @@ -37,6 +38,7 @@ drops = { path = "./drops" } trade = { path = "./trade" } room = { path = "./room" } patch_server = { path = "./patch_server" } +login_server = { path = "./login_server" } libpso = { git = "http://git.sharnoth.com/jake/libpso" } @@ -83,6 +85,7 @@ drops = { workspace = true } trade = { workspace = true } room = { workspace = true } patch_server = { workspace = true } +login_server = { workspace = true } libpso = { workspace = true } diff --git a/login_server/Cargo.toml b/login_server/Cargo.toml new file mode 100644 index 0000000..8ce2441 --- /dev/null +++ b/login_server/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "login_server" +version = "0.1.0" +edition = "2021" + +[dependencies] +entity = { workspace = true } +networking = { workspace = true } +pktbuilder = { workspace = true } +stats = { workspace = true } + +libpso = { workspace = true } + +async-std = { workspace = true } +async-trait = { workspace = true } +anyhow = { workspace = true } +bcrypt = { workspace = true } +crc = { workspace = true } +thiserror = { workspace = true } +chrono = { workspace = true } +rand= { workspace = true } diff --git a/src/login/character.rs b/login_server/src/character.rs similarity index 99% rename from src/login/character.rs rename to login_server/src/character.rs index 6529f3d..ec9d3d3 100644 --- a/src/login/character.rs +++ b/login_server/src/character.rs @@ -31,7 +31,7 @@ use entity::item::tool::Tool; use entity::item::mag::Mag; use entity::character::{CharacterEntity, NewCharacterEntity, CharacterClass, TechLevel}; -use crate::login::login::{get_login_status}; +use crate::login::get_login_status; use networking::interserver::AuthToken; use pktbuilder::ship::SHIP_MENU_ID; diff --git a/login_server/src/lib.rs b/login_server/src/lib.rs new file mode 100644 index 0000000..0006241 --- /dev/null +++ b/login_server/src/lib.rs @@ -0,0 +1,2 @@ +pub mod login; +pub mod character; diff --git a/src/login/login.rs b/login_server/src/login.rs similarity index 98% rename from src/login/login.rs rename to login_server/src/login.rs index cdc32d9..70bb5a4 100644 --- a/src/login/login.rs +++ b/login_server/src/login.rs @@ -83,21 +83,13 @@ pub async fn get_login_status(entity_gateway: &mut impl EntityGateway, pkt: &Log pub fn check_if_already_online(user: UserAccountEntity) -> Result { Ok(user) - /* - if user.is_currently_online() { - Err(AccountStatus::PayUp) -} - else { - Ok(user) -} - */ } #[derive(Clone)] pub struct LoginServerState { character_server_ip: net::Ipv4Addr, entity_gateway: EG, - clients: HashMap, + clients: HashMap, // TODO: this should be arc/mutex'd? } impl LoginServerState { @@ -119,7 +111,7 @@ impl LoginServerState { let response = SendLoginPacket::LoginResponse(LoginResponse::by_status(AccountStatus::Ok, pkt.session)); let ip = u32::from_ne_bytes(self.character_server_ip.octets()); Ok(vec![response, - SendLoginPacket::RedirectClient(RedirectClient::new(ip, crate::login::character::CHARACTER_PORT))]) + SendLoginPacket::RedirectClient(RedirectClient::new(ip, crate::character::CHARACTER_PORT))]) }, Err(err) => { Ok(vec![SendLoginPacket::LoginResponse(LoginResponse::by_status(err, pkt.session))]) diff --git a/src/bin/login.rs b/src/bin/login.rs index f4c5335..8f8832b 100644 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -1,7 +1,7 @@ use log::{info}; use entity::gateway::postgres::PostgresGateway; -use elseware::login::login::LoginServerState; -use elseware::login::character::CharacterServerState; +use login_server::login::LoginServerState; +use login_server::character::CharacterServerState; use networking::interserver::AuthToken; fn main() { @@ -38,17 +38,17 @@ fn main() { let login_state = LoginServerState::new(entity_gateway.clone(), charserv_ip); let login_loop = async_std::task::spawn(async move { - networking::mainloop::run_server(login_state, elseware::login::login::LOGIN_PORT).await; + networking::mainloop::run_server(login_state, login_server::login::LOGIN_PORT).await; }); let char_state = CharacterServerState::new(entity_gateway, AuthToken(shipgate_token)); let sub_char_state = char_state.clone(); let character_loop = async_std::task::spawn(async move { - networking::mainloop::run_server(sub_char_state, elseware::login::character::CHARACTER_PORT).await; + networking::mainloop::run_server(sub_char_state, login_server::character::CHARACTER_PORT).await; }); let inter_character_loop = async_std::task::spawn(async move { - networking::mainloop::run_interserver_listen(char_state, elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_listen(char_state, login_server::login::COMMUNICATION_PORT).await; }); info!("[auth/character] starting server"); diff --git a/src/bin/main.rs b/src/bin/main.rs index a61bf7b..e12ad1b 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -2,8 +2,8 @@ use std::net::Ipv4Addr; use log::{info}; use networking::interserver::AuthToken; -use elseware::login::login::LoginServerState; -use elseware::login::character::CharacterServerState; +use login_server::login::LoginServerState; +use login_server::character::CharacterServerState; use patch_server::{PatchServerState, generate_patch_tree, load_config, load_motd}; use elseware::ship::ship::ShipServerStateBuilder; @@ -344,19 +344,19 @@ fn main() { info!("[auth] starting server"); let login_state = LoginServerState::new(entity_gateway.clone(), "127.0.0.1".parse().unwrap()); let login_loop = async_std::task::spawn(async move { - networking::mainloop::run_server(login_state, elseware::login::login::LOGIN_PORT).await; + networking::mainloop::run_server(login_state, login_server::login::LOGIN_PORT).await; }); info!("[character] starting server"); let char_state = CharacterServerState::new(entity_gateway.clone(), AuthToken("".into())); let sub_char_state = char_state.clone(); let character_loop = async_std::task::spawn(async move { - networking::mainloop::run_server(sub_char_state, elseware::login::character::CHARACTER_PORT).await; + networking::mainloop::run_server(sub_char_state, login_server::character::CHARACTER_PORT).await; }); let sub_char_state = char_state.clone(); let inter_character_loop = async_std::task::spawn(async move { - networking::mainloop::run_interserver_listen(sub_char_state, elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_listen(sub_char_state, login_server::login::COMMUNICATION_PORT).await; }); info!("[ship] starting servers"); @@ -373,7 +373,7 @@ fn main() { }); let sub_ship_state = ship_state.clone(); let inter_ship_loop1 = async_std::task::spawn(async move { - networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), login_server::login::COMMUNICATION_PORT).await; }); let ship_state = ShipServerStateBuilder::default() @@ -389,7 +389,7 @@ fn main() { }); let sub_ship_state = ship_state.clone(); let inter_ship_loop2 = async_std::task::spawn(async move { - networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), login_server::login::COMMUNICATION_PORT).await; }); let ship_state = ShipServerStateBuilder::default() @@ -404,7 +404,7 @@ fn main() { }); let sub_ship_state = ship_state.clone(); let inter_ship_loop3 = async_std::task::spawn(async move { - networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), login_server::login::COMMUNICATION_PORT).await; }); futures::future::join_all(vec![patch_loop, login_loop, character_loop, inter_character_loop, diff --git a/src/bin/ship.rs b/src/bin/ship.rs index c021601..cfa50ed 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -52,7 +52,7 @@ fn main() { networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT).await; }); let inter_ship_loop = async_std::task::spawn(async move { - networking::mainloop::run_interserver_connect(ship_state, shipgate_ip, elseware::login::login::COMMUNICATION_PORT).await; + networking::mainloop::run_interserver_connect(ship_state, shipgate_ip, login_server::login::COMMUNICATION_PORT).await; }); info!("[auth/character] starting server"); diff --git a/src/lib.rs b/src/lib.rs index 5436b77..3b52841 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,5 +11,5 @@ extern crate test; //pub mod common; //pub mod entity; //pub mod patch; -pub mod login; +//pub mod login; pub mod ship; diff --git a/src/login/mod.rs b/src/login/mod.rs deleted file mode 100644 index a5b3370..0000000 --- a/src/login/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -#[allow(clippy::module_inception)] -pub mod login; -pub mod character; diff --git a/src/ship/packet/handler/auth.rs b/src/ship/packet/handler/auth.rs index 915da68..891ae6e 100644 --- a/src/ship/packet/handler/auth.rs +++ b/src/ship/packet/handler/auth.rs @@ -2,7 +2,7 @@ use libpso::packet::login::{Login, LoginResponse, AccountStatus, Session}; use libpso::packet::ship::*; use networking::serverstate::ClientId; use crate::ship::ship::{SendShipPacket, ShipError, ClientState, Clients}; -use crate::login::login::get_login_status; +use login_server::login::get_login_status; use entity::gateway::EntityGateway; use items::state::ItemState; use networking::interserver::ShipMessage; -- 2.36.0 From 7ab0088c26d58d591465f68aa41d5adf18b85c76 Mon Sep 17 00:00:00 2001 From: jake Date: Mon, 13 Nov 2023 23:27:12 -0700 Subject: [PATCH 55/58] move ship server into its own crate --- Cargo.toml | 3 + ship_server/Cargo.toml | 32 ++++ .../handler => ship_server/src}/auth.rs | 3 +- {src/ship => ship_server/src}/chatcommand.rs | 2 +- .../src}/communication.rs | 4 +- .../src}/direct_message.rs | 2 +- src/ship/ship.rs => ship_server/src/lib.rs | 157 +++++++++--------- .../handler => ship_server/src}/lobby.rs | 3 +- .../handler => ship_server/src}/message.rs | 2 +- .../handler => ship_server/src}/quest.rs | 2 +- .../handler => ship_server/src}/room.rs | 2 +- .../handler => ship_server/src}/settings.rs | 2 +- .../handler => ship_server/src}/ship.rs | 2 +- .../handler => ship_server/src}/trade.rs | 2 +- src/bin/main.rs | 14 +- src/bin/ship.rs | 6 +- src/lib.rs | 15 -- src/ship/mod.rs | 4 - src/ship/packet/handler/mod.rs | 10 -- src/ship/packet/mod.rs | 2 - tests/common.rs | 2 +- tests/test_bank.rs | 2 +- tests/test_character.rs | 2 +- tests/test_exp_gain.rs | 2 +- tests/test_item_actions.rs | 2 +- tests/test_item_drop.rs | 2 +- tests/test_item_id.rs | 2 +- tests/test_item_pickup.rs | 2 +- tests/test_item_use.rs | 2 +- tests/test_mags.rs | 2 +- tests/test_rooms.rs | 2 +- tests/test_shops.rs | 2 +- tests/test_trade.rs | 4 +- 33 files changed, 155 insertions(+), 142 deletions(-) create mode 100644 ship_server/Cargo.toml rename {src/ship/packet/handler => ship_server/src}/auth.rs (96%) rename {src/ship => ship_server/src}/chatcommand.rs (98%) rename {src/ship/packet/handler => ship_server/src}/communication.rs (96%) rename {src/ship/packet/handler => ship_server/src}/direct_message.rs (99%) rename src/ship/ship.rs => ship_server/src/lib.rs (80%) rename {src/ship/packet/handler => ship_server/src}/lobby.rs (99%) rename {src/ship/packet/handler => ship_server/src}/message.rs (99%) rename {src/ship/packet/handler => ship_server/src}/quest.rs (99%) rename {src/ship/packet/handler => ship_server/src}/room.rs (99%) rename {src/ship/packet/handler => ship_server/src}/settings.rs (98%) rename {src/ship/packet/handler => ship_server/src}/ship.rs (95%) rename {src/ship/packet/handler => ship_server/src}/trade.rs (99%) delete mode 100644 src/lib.rs delete mode 100644 src/ship/mod.rs delete mode 100644 src/ship/packet/handler/mod.rs delete mode 100644 src/ship/packet/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 19347e4..a514c54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ members = [ "trade", "patch_server", "login_server", + "ship_server", ] [workspace.dependencies] @@ -39,6 +40,7 @@ trade = { path = "./trade" } room = { path = "./room" } patch_server = { path = "./patch_server" } login_server = { path = "./login_server" } +ship_server = { path = "./ship_server" } libpso = { git = "http://git.sharnoth.com/jake/libpso" } @@ -86,6 +88,7 @@ trade = { workspace = true } room = { workspace = true } patch_server = { workspace = true } login_server = { workspace = true } +ship_server = { workspace = true } libpso = { workspace = true } diff --git a/ship_server/Cargo.toml b/ship_server/Cargo.toml new file mode 100644 index 0000000..604dda8 --- /dev/null +++ b/ship_server/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "ship_server" +version = "0.1.0" +edition = "2021" + +[dependencies] +networking = { workspace = true } +trade = { workspace = true } +maps = { workspace = true } +location = { workspace = true } +room = { workspace = true } +shops = { workspace = true } +client = { workspace = true } +pktbuilder = { workspace = true } +items = { workspace = true } +entity = { workspace = true } +drops = { workspace = true } +quests = { workspace = true } +stats = { workspace = true } + +login_server = { workspace = true } + +libpso = { workspace = true } + +async-std = { workspace = true } +async-trait = { workspace = true } +log = { workspace = true } +anyhow = { workspace = true } +thiserror = { workspace = true } +rand = { workspace = true } +serde = { workspace = true } +futures = { workspace = true } diff --git a/src/ship/packet/handler/auth.rs b/ship_server/src/auth.rs similarity index 96% rename from src/ship/packet/handler/auth.rs rename to ship_server/src/auth.rs index 891ae6e..b8f746e 100644 --- a/src/ship/packet/handler/auth.rs +++ b/ship_server/src/auth.rs @@ -1,7 +1,8 @@ use libpso::packet::login::{Login, LoginResponse, AccountStatus, Session}; use libpso::packet::ship::*; use networking::serverstate::ClientId; -use crate::ship::ship::{SendShipPacket, ShipError, ClientState, Clients}; +use crate::{SendShipPacket, ShipError}; +use client::{Clients, ClientState}; use login_server::login::get_login_status; use entity::gateway::EntityGateway; use items::state::ItemState; diff --git a/src/ship/chatcommand.rs b/ship_server/src/chatcommand.rs similarity index 98% rename from src/ship/chatcommand.rs rename to ship_server/src/chatcommand.rs index 7799e17..a2d3ff1 100644 --- a/src/ship/chatcommand.rs +++ b/ship_server/src/chatcommand.rs @@ -1,7 +1,7 @@ use libpso::packet::ship::PlayerChat; use entity::gateway::EntityGateway; use networking::serverstate::ClientId; -use crate::ship::ship::{ShipServerState, SendShipPacket}; +use crate::{ShipServerState, SendShipPacket}; use client::Clients; use items::state::ItemState; use entity::item::{BankName, BankIdentifier}; diff --git a/src/ship/packet/handler/communication.rs b/ship_server/src/communication.rs similarity index 96% rename from src/ship/packet/handler/communication.rs rename to ship_server/src/communication.rs index 3982efc..4949acd 100644 --- a/src/ship/packet/handler/communication.rs +++ b/ship_server/src/communication.rs @@ -1,7 +1,7 @@ use libpso::packet::ship::*; use networking::serverstate::ClientId; -use crate::ship::ship::{SendShipPacket, Clients}; -use location::{ClientLocation}; +use crate::{SendShipPacket, Clients}; +use location::ClientLocation; use entity::gateway::EntityGateway; use futures::future::join_all; diff --git a/src/ship/packet/handler/direct_message.rs b/ship_server/src/direct_message.rs similarity index 99% rename from src/ship/packet/handler/direct_message.rs rename to ship_server/src/direct_message.rs index c93ae0d..9ec6f52 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/ship_server/src/direct_message.rs @@ -6,7 +6,7 @@ use libpso::packet::ship::*; use libpso::packet::messages::*; use stats::leveltable::LEVEL_TABLE; use networking::serverstate::ClientId; -use crate::ship::ship::{SendShipPacket, ShipError, Clients}; +use crate::{SendShipPacket, ShipError, Clients}; use location::ClientLocation; use drops::ItemDrop; use room::Rooms; diff --git a/src/ship/ship.rs b/ship_server/src/lib.rs similarity index 80% rename from src/ship/ship.rs rename to ship_server/src/lib.rs index f9816c2..f6d0ed1 100644 --- a/src/ship/ship.rs +++ b/ship_server/src/lib.rs @@ -1,4 +1,16 @@ -#![allow(dead_code, unused_must_use)] +#![allow(clippy::type_complexity)] +mod auth; +mod communication; +mod direct_message; +mod lobby; +mod message; +mod room; +mod settings; +mod quest; +mod ship; +pub mod trade; +mod chatcommand; + use std::net::Ipv4Addr; use async_std::channel; @@ -22,18 +34,15 @@ use entity::character::SectionID; use entity::room::RoomNote; use location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; use drops::{DropTable, StandardDropTable}; -use items; -use room; +use ::room::{Rooms, RoomCreationError}; use maps::room::{RoomMode, Episode, Difficulty}; use quests::{load_standard_quests, load_government_quests}; use quests::{QuestList, QuestLoadError}; use maps::Holiday; use maps::area::MapAreaError; use maps::maps::{Maps, MapsError, generate_free_roam_maps}; -use crate::ship::packet::handler; use shops::{ItemShops, StandardItemShops}; -use trade::TradeState; -use crate::ship::chatcommand; +use ::trade::{TradeState, TradeStateError}; use pktbuilder::quest::{QUEST_CATEGORY_MENU_ID, QUEST_SELECT_MENU_ID}; pub use client::{Clients, ClientState}; @@ -98,13 +107,13 @@ pub enum ShipError { #[error("invalid item {0}")] InvalidItem(items::ClientItemId), #[error("trade error {0}")] - TradeError(#[from] crate::ship::packet::handler::trade::TradeError), + TradeError(#[from] trade::TradeError), #[error("trade state error {0}")] - TradeStateError(#[from] trade::TradeStateError), + TradeStateError(#[from] TradeStateError), #[error("message error {0}")] - MessageError(#[from] crate::ship::packet::handler::direct_message::MessageError), + MessageError(#[from] crate::direct_message::MessageError), #[error("room creation error {0}")] - RoomCreationError(#[from] room::RoomCreationError), + RoomCreationError(#[from] RoomCreationError), #[error("channel send error {0}")] SendError(#[from] async_std::channel::SendError), } @@ -432,7 +441,7 @@ impl ShipServerStateBuilder { #[derive(Clone, Default)] pub struct Block { client_location: ClientLocation, - pub rooms: room::Rooms, + pub rooms: Rooms, } #[derive(Clone)] @@ -481,58 +490,58 @@ impl ShipServerState { Ok(match msg.msg { GameMessage::RequestExp(request_exp) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::message::request_exp(id, request_exp, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms).await? + message::request_exp(id, request_exp, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms).await? }, GameMessage::PlayerDropItem(player_drop_item) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::message::player_drop_item(id, player_drop_item, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await? + message::player_drop_item(id, player_drop_item, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await? }, GameMessage::DropCoordinates(drop_coordinates) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::message::drop_coordinates(id, drop_coordinates, &block.client_location, &self.clients, &block.rooms).await? + message::drop_coordinates(id, drop_coordinates, &block.client_location, &self.clients, &block.rooms).await? }, GameMessage::PlayerNoLongerHasItem(no_longer_has_item) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::message::no_longer_has_item(id, no_longer_has_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? + message::no_longer_has_item(id, no_longer_has_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? }, GameMessage::PlayerChangedMap(_) | GameMessage::PlayerChangedMap2(_) | GameMessage::TellOtherPlayerMyLocation(_) | GameMessage::PlayerWarpingToFloor(_) | GameMessage::PlayerTeleported(_) | GameMessage::PlayerStopped(_) | GameMessage::PlayerLoadedIn(_) | GameMessage::PlayerWalking(_) | GameMessage::PlayerRunning(_) | GameMessage::PlayerWarped(_) | GameMessage::PlayerChangedFloor(_) | GameMessage::InitializeSpeechNpc(_) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::message::update_player_position(id, msg, &self.clients, &block.client_location, &block.rooms).await? + message::update_player_position(id, msg, &self.clients, &block.client_location, &block.rooms).await? }, GameMessage::ChargeAttack(charge_attack) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::message::charge_attack(id, charge_attack, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? + message::charge_attack(id, charge_attack, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? }, GameMessage::PlayerUseItem(player_use_item) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::message::player_uses_item(id, player_use_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? + message::player_uses_item(id, player_use_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? }, GameMessage::PlayerUsedMedicalCenter(player_used_medical_center) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::message::player_used_medical_center(id, player_used_medical_center, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? + message::player_used_medical_center(id, player_used_medical_center, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? }, GameMessage::PlayerFeedMag(player_feed_mag) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::message::player_feed_mag(id, player_feed_mag, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? + message::player_feed_mag(id, player_feed_mag, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? }, GameMessage::PlayerEquipItem(player_equip_item) => { - handler::message::player_equips_item(id, player_equip_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? + message::player_equips_item(id, player_equip_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? }, GameMessage::PlayerUnequipItem(player_unequip_item) => { - handler::message::player_unequips_item(id, player_unequip_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? + message::player_unequips_item(id, player_unequip_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? }, GameMessage::SortItems(sort_items) => { - handler::message::player_sorts_items(id, sort_items, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? + message::player_sorts_items(id, sort_items, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? }, GameMessage::PlayerSoldItem(player_sold_item) => { - handler::message::player_sells_item(id, player_sold_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? + message::player_sells_item(id, player_sold_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? }, GameMessage::FloorItemLimitItemDeletion(floor_item_limit_delete) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::message::floor_item_limit_deletion(id, floor_item_limit_delete, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await? + message::floor_item_limit_deletion(id, floor_item_limit_delete, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await? }, _ => { let cmsg = msg.clone(); @@ -551,37 +560,37 @@ impl ShipServerState { let block = self.blocks.get_from_client(id, &self.clients).await?; Ok(match msg.msg { GameMessage::GuildcardSend(guildcard_send) => { - handler::direct_message::guildcard_send(id, guildcard_send, target, &block.client_location, &self.clients).await? + direct_message::guildcard_send(id, guildcard_send, target, &block.client_location, &self.clients).await? }, GameMessage::RequestItem(request_item) => { - handler::direct_message::request_item(id, request_item, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await? + direct_message::request_item(id, request_item, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await? }, GameMessage::PickupItem(pickup_item) => { - handler::direct_message::pickup_item(id, pickup_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? + direct_message::pickup_item(id, pickup_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? }, GameMessage::BoxDropRequest(box_drop_request) => { - handler::direct_message::request_box_item(id, box_drop_request, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await? + direct_message::request_box_item(id, box_drop_request, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await? }, GameMessage::BankRequest(_bank_request) => { - handler::direct_message::send_bank_list(id, &self.clients, &mut self.item_state).await? + direct_message::send_bank_list(id, &self.clients, &mut self.item_state).await? }, GameMessage::BankInteraction(bank_interaction) => { - handler::direct_message::bank_interaction(id, bank_interaction, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? + direct_message::bank_interaction(id, bank_interaction, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? }, GameMessage::ShopRequest(shop_request) => { - handler::direct_message::shop_request(id, shop_request, &block.client_location, &self.clients, &block.rooms, &self.shops).await? + direct_message::shop_request(id, shop_request, &block.client_location, &self.clients, &block.rooms, &self.shops).await? }, GameMessage::BuyItem(buy_item) => { - handler::direct_message::buy_item(id, buy_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? + direct_message::buy_item(id, buy_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? }, GameMessage::TekRequest(tek_request) => { - handler::direct_message::request_tek_item(id, tek_request, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? + direct_message::request_tek_item(id, tek_request, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? }, GameMessage::TekAccept(tek_accept) => { - handler::direct_message::accept_tek_item(id, tek_accept, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? + direct_message::accept_tek_item(id, tek_accept, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? }, GameMessage::TradeRequest(trade_request) => { - handler::trade::trade_request(id, trade_request, target, &block.client_location, &self.clients, &mut self.item_state, &mut self.trades).await? + trade::trade_request(id, trade_request, target, &block.client_location, &self.clients, &mut self.item_state, &mut self.trades).await? }, _ => { let cmsg = msg.clone(); @@ -627,7 +636,7 @@ impl ServerState for ShipServerState { Ok(match pkt { RecvShipPacket::Login(login) => { - handler::auth::validate_login(id, login, &mut self.entity_gateway, &mut self.clients, &mut self.item_state, &self.shipgate_sender, &self.name, self.blocks.0.len()) + auth::validate_login(id, login, &mut self.entity_gateway, &mut self.clients, &mut self.item_state, &self.shipgate_sender, &self.name, self.blocks.0.len()) .await? .into_iter() .map(move |pkt| (id, pkt)) @@ -636,7 +645,7 @@ impl ServerState for ShipServerState { RecvShipPacket::QuestDetailRequest(questdetailrequest) => { let block = self.blocks.get_from_client(id, &self.clients).await?; match questdetailrequest.menu { - QUEST_SELECT_MENU_ID => handler::quest::quest_detail(id, questdetailrequest, &block.client_location, &block.rooms).await?, + QUEST_SELECT_MENU_ID => quest::quest_detail(id, questdetailrequest, &block.client_location, &block.rooms).await?, _ => unreachable!(), } }, @@ -644,27 +653,27 @@ impl ServerState for ShipServerState { let block = self.blocks.get_from_client(id, &self.clients).await?; match menuselect.menu { SHIP_MENU_ID => { - let leave_lobby = handler::lobby::remove_from_lobby(id, &mut block.client_location).await.into_iter().flatten(); - let select_ship = handler::ship::selected_ship(id, menuselect, &self.ship_list).await?; + let leave_lobby = lobby::remove_from_lobby(id, &mut block.client_location).await.into_iter().flatten(); + let select_ship = ship::selected_ship(id, menuselect, &self.ship_list).await?; leave_lobby.chain(select_ship).collect() } BLOCK_MENU_ID => { - let leave_lobby = handler::lobby::remove_from_lobby(id, &mut block.client_location).await.into_iter().flatten(); - let select_block = handler::lobby::block_selected(id, menuselect, &self.clients, &self.item_state).await?.into_iter(); + let leave_lobby = lobby::remove_from_lobby(id, &mut block.client_location).await.into_iter().flatten(); + let select_block = lobby::block_selected(id, menuselect, &self.clients, &self.item_state).await?.into_iter(); leave_lobby.chain(select_block).collect() } - ROOM_MENU_ID => handler::room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await?, - QUEST_CATEGORY_MENU_ID => handler::quest::select_quest_category(id, menuselect, &block.client_location, &block.rooms).await?, + ROOM_MENU_ID => room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await?, + QUEST_CATEGORY_MENU_ID => quest::select_quest_category(id, menuselect, &block.client_location, &block.rooms).await?, _ => unreachable!(), } }, RecvShipPacket::QuestMenuSelect(questmenuselect) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::quest::player_chose_quest(id, questmenuselect, &self.clients, &block.client_location, &block.rooms, self.event).await? + quest::player_chose_quest(id, questmenuselect, &self.clients, &block.client_location, &block.rooms, self.event).await? }, RecvShipPacket::MenuDetail(menudetail) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::lobby::get_room_tab_info(id, menudetail, &mut block.client_location, &self.clients).await? + lobby::get_room_tab_info(id, menudetail, &mut block.client_location, &self.clients).await? }, RecvShipPacket::RoomPasswordReq(room_password_req) => { let block = self.blocks.get_from_client(id, &self.clients).await?; @@ -678,7 +687,7 @@ impl ServerState for ShipServerState { menu: room_password_req.menu, item: room_password_req.item, }; - handler::room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await? + room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await? } else { vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("Incorrect password".into())))] @@ -686,7 +695,7 @@ impl ServerState for ShipServerState { }, RecvShipPacket::CharData(chardata) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::lobby::send_player_to_lobby(id, chardata, &mut block.client_location, &self.clients, &self.item_state, self.event).await? + lobby::send_player_to_lobby(id, chardata, &mut block.client_location, &self.clients, &self.item_state, self.event).await? }, RecvShipPacket::Message(msg) => { self.message(id, msg).await? @@ -704,40 +713,40 @@ impl ServerState for ShipServerState { }, None => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::communication::player_chat(id, msg, &block.client_location, &self.clients).await? + communication::player_chat(id, msg, &block.client_location, &self.clients).await? } } }, RecvShipPacket::CreateRoom(create_room) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::room::create_room(id, create_room, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, + room::create_room(id, create_room, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.map_builder.clone(), self.drop_table_builder.clone(), self.standard_quest_builder.clone(), self.government_quest_builder.clone(), self.event).await? }, RecvShipPacket::RoomNameRequest(_req) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::room::room_name_request(id, &block.client_location, &block.rooms).await? + room::room_name_request(id, &block.client_location, &block.rooms).await? }, RecvShipPacket::UpdateTechMenu(pkt) => { - handler::settings::update_tech_menu(id, pkt, &self.clients, &mut self.entity_gateway).await? + settings::update_tech_menu(id, pkt, &self.clients, &mut self.entity_gateway).await? }, RecvShipPacket::UpdateConfig(pkt) => { - handler::settings::update_config(id, pkt, &self.clients, &mut self.entity_gateway).await? + settings::update_config(id, pkt, &self.clients, &mut self.entity_gateway).await? }, RecvShipPacket::ViewInfoboardRequest(_pkt) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::communication::request_infoboard(id, &block.client_location, &self.clients).await? + communication::request_infoboard(id, &block.client_location, &self.clients).await? }, RecvShipPacket::WriteInfoboard(pkt) => { - handler::communication::write_infoboard(id, pkt, &self.clients, &mut self.entity_gateway).await? + communication::write_infoboard(id, pkt, &self.clients, &mut self.entity_gateway).await? }, RecvShipPacket::RoomListRequest(_req) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::room::request_room_list(id, &block.client_location, &block.rooms).await + room::request_room_list(id, &block.client_location, &block.rooms).await }, RecvShipPacket::Like62ButCooler(cool62) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::room::cool_62(id, cool62, &block.client_location).await? + room::cool_62(id, cool62, &block.client_location).await? }, RecvShipPacket::ClientCharacterData(_) => { // TOOD: validate this in some way? @@ -745,57 +754,57 @@ impl ServerState for ShipServerState { }, RecvShipPacket::DoneBursting(_) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::room::done_bursting(id, &block.client_location, &block.rooms).await? + room::done_bursting(id, &block.client_location, &block.rooms).await? }, RecvShipPacket::DoneBursting2(_) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::room::done_bursting(id, &block.client_location, &block.rooms).await? + room::done_bursting(id, &block.client_location, &block.rooms).await? }, RecvShipPacket::LobbySelect(pkt) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::lobby::change_lobby(id, pkt.lobby, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, &mut self.entity_gateway, self.event).await? + lobby::change_lobby(id, pkt.lobby, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, &mut self.entity_gateway, self.event).await? }, RecvShipPacket::RequestQuestList(rql) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::quest::send_quest_category_list(id, rql, &block.client_location, &block.rooms).await? + quest::send_quest_category_list(id, rql, &block.client_location, &block.rooms).await? }, RecvShipPacket::QuestFileRequest(quest_file_request) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::quest::quest_file_request(id, quest_file_request, &block.client_location, &mut block.rooms).await? + quest::quest_file_request(id, quest_file_request, &block.client_location, &mut block.rooms).await? }, RecvShipPacket::QuestChunkAck(quest_chunk_ack) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::quest::quest_chunk_ack(id, quest_chunk_ack, &block.client_location, &block.rooms).await? + quest::quest_chunk_ack(id, quest_chunk_ack, &block.client_location, &block.rooms).await? }, RecvShipPacket::DoneLoadingQuest(_) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::quest::done_loading_quest(id, &self.clients, &block.client_location).await? + quest::done_loading_quest(id, &self.clients, &block.client_location).await? }, RecvShipPacket::FullCharacterData(_full_character_data) => { Vec::new() }, RecvShipPacket::SaveOptions(save_options) => { - handler::settings::save_options(id, save_options, &self.clients, &mut self.entity_gateway).await? + settings::save_options(id, save_options, &self.clients, &mut self.entity_gateway).await? }, RecvShipPacket::RequestShipList(_) => { - handler::ship::ship_list(id, &self.ship_list).await + ship::ship_list(id, &self.ship_list).await }, RecvShipPacket::RequestShipBlockList(_) => { - handler::ship::block_list(id, &self.name, self.blocks.0.len()) + ship::block_list(id, &self.name, self.blocks.0.len()) }, RecvShipPacket::ItemsToTrade(items_to_trade) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::trade::items_to_trade(id, items_to_trade, &block.client_location, &self.clients, &mut self.item_state, &mut self.trades).await? + trade::items_to_trade(id, items_to_trade, &block.client_location, &self.clients, &mut self.item_state, &mut self.trades).await? }, RecvShipPacket::TradeConfirmed(_) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::trade::trade_confirmed(id, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state, &mut self.trades).await? + trade::trade_confirmed(id, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state, &mut self.trades).await? }, RecvShipPacket::KeyboardConfig(keyboard_config) => { - handler::settings::keyboard_config(id, keyboard_config, &self.clients, &mut self.entity_gateway).await? + settings::keyboard_config(id, keyboard_config, &self.clients, &mut self.entity_gateway).await? }, RecvShipPacket::GamepadConfig(gamepad_config) => { - handler::settings::gamepad_config(id, gamepad_config, &self.clients, &mut self.entity_gateway).await? + settings::gamepad_config(id, gamepad_config, &self.clients, &mut self.entity_gateway).await? }, }) } @@ -816,7 +825,7 @@ impl ServerState for ShipServerState { entity_gateway.add_room_note(room.room_id, RoomNote::PlayerJoin { character_id, }).await - })}).await; + })}).await??; if neighbors.is_empty() { block.rooms.remove(room).await; } @@ -831,9 +840,9 @@ impl ServerState for ShipServerState { if let Some(mut client) = self.clients.remove(&id).await { client.user.at_ship = false; - self.entity_gateway.save_user(&client.user).await; + self.entity_gateway.save_user(&client.user).await?; if let Some(shipgate_sender) = self.shipgate_sender.as_ref() { - shipgate_sender.send(ShipMessage::RemoveUser(client.user.id)).await; + shipgate_sender.send(ShipMessage::RemoveUser(client.user.id)).await?; } self.item_state.remove_character_from_room(&client.character).await } diff --git a/src/ship/packet/handler/lobby.rs b/ship_server/src/lobby.rs similarity index 99% rename from src/ship/packet/handler/lobby.rs rename to ship_server/src/lobby.rs index 3033091..8e6090a 100644 --- a/src/ship/packet/handler/lobby.rs +++ b/ship_server/src/lobby.rs @@ -1,13 +1,12 @@ use libpso::packet::ship::*; use networking::serverstate::ClientId; use stats::leveltable::LEVEL_TABLE; -use crate::ship::ship::{SendShipPacket, ShipError}; +use crate::{SendShipPacket, ShipError}; use maps::Holiday; use client::Clients; use room::Rooms; use pktbuilder::character::FullCharacterBytesBuilder; use location::{ClientLocation, LobbyId, RoomLobby, ClientLocationError, RoomId}; -//use pktbuilder; use items::state::ItemState; use entity::gateway::EntityGateway; use entity::room::RoomNote; diff --git a/src/ship/packet/handler/message.rs b/ship_server/src/message.rs similarity index 99% rename from src/ship/packet/handler/message.rs rename to ship_server/src/message.rs index ca731c9..31a6541 100644 --- a/src/ship/packet/handler/message.rs +++ b/ship_server/src/message.rs @@ -4,7 +4,7 @@ use entity::gateway::EntityGateway; use entity::item::Meseta; use networking::serverstate::ClientId; use stats::leveltable::LEVEL_TABLE; -use crate::ship::ship::{SendShipPacket, ShipError}; +use crate::{SendShipPacket, ShipError}; use client::{Clients, ItemDropLocation}; use ::room::Rooms; use location::{ClientLocation, ClientLocationError}; diff --git a/src/ship/packet/handler/quest.rs b/ship_server/src/quest.rs similarity index 99% rename from src/ship/packet/handler/quest.rs rename to ship_server/src/quest.rs index 6193530..b40c718 100644 --- a/src/ship/packet/handler/quest.rs +++ b/ship_server/src/quest.rs @@ -2,7 +2,7 @@ use std::io::{Cursor, Read, Seek, SeekFrom}; use futures::stream::{FuturesOrdered, StreamExt}; use libpso::packet::ship::*; use networking::serverstate::ClientId; -use crate::ship::ship::{SendShipPacket, ShipError}; +use crate::{SendShipPacket, ShipError}; use client::Clients; use maps::Holiday; use room::Rooms; diff --git a/src/ship/packet/handler/room.rs b/ship_server/src/room.rs similarity index 99% rename from src/ship/packet/handler/room.rs rename to ship_server/src/room.rs index 563385d..254fdd0 100644 --- a/src/ship/packet/handler/room.rs +++ b/ship_server/src/room.rs @@ -11,7 +11,7 @@ use entity::gateway::EntityGateway; use entity::character::SectionID; use entity::room::{NewRoomEntity, RoomEntityMode, RoomNote}; use drops::DropTable; -use crate::ship::ship::SendShipPacket; +use crate::SendShipPacket; use client::Clients; use room::{Rooms, RoomState, RoomCreationError}; use maps::Holiday; diff --git a/src/ship/packet/handler/settings.rs b/ship_server/src/settings.rs similarity index 98% rename from src/ship/packet/handler/settings.rs rename to ship_server/src/settings.rs index 4bd665d..b21491b 100644 --- a/src/ship/packet/handler/settings.rs +++ b/ship_server/src/settings.rs @@ -1,6 +1,6 @@ use libpso::packet::ship::*; use networking::serverstate::ClientId; -use crate::ship::ship::{SendShipPacket, Clients}; +use crate::{SendShipPacket, Clients}; use entity::gateway::EntityGateway; pub async fn update_config(id: ClientId, diff --git a/src/ship/packet/handler/ship.rs b/ship_server/src/ship.rs similarity index 95% rename from src/ship/packet/handler/ship.rs rename to ship_server/src/ship.rs index 762e73f..a006004 100644 --- a/src/ship/packet/handler/ship.rs +++ b/ship_server/src/ship.rs @@ -3,7 +3,7 @@ use libpso::packet::ship::*; use libpso::packet::login::RedirectClient; use networking::serverstate::ClientId; use networking::interserver::Ship; -use crate::ship::ship::{SendShipPacket, ShipError}; +use crate::{SendShipPacket, ShipError}; use pktbuilder as builder; pub async fn ship_list(id: ClientId, ship_list: &Arc>>) -> Vec<(ClientId, SendShipPacket)> { diff --git a/src/ship/packet/handler/trade.rs b/ship_server/src/trade.rs similarity index 99% rename from src/ship/packet/handler/trade.rs rename to ship_server/src/trade.rs index 8da8f38..b57b218 100644 --- a/src/ship/packet/handler/trade.rs +++ b/ship_server/src/trade.rs @@ -2,7 +2,7 @@ use std::convert::TryInto; use libpso::packet::ship::*; use libpso::packet::messages::*; use networking::serverstate::ClientId; -use crate::ship::ship::{SendShipPacket, ShipError, Clients}; +use crate::{SendShipPacket, ShipError, Clients}; use location::{ClientLocation}; use items::ClientItemId; use items::state::{ItemState, ItemStateError}; diff --git a/src/bin/main.rs b/src/bin/main.rs index e12ad1b..ec67554 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -5,7 +5,7 @@ use networking::interserver::AuthToken; use login_server::login::LoginServerState; use login_server::character::CharacterServerState; use patch_server::{PatchServerState, generate_patch_tree, load_config, load_motd}; -use elseware::ship::ship::ShipServerStateBuilder; +use ship_server::ShipServerStateBuilder; use maps::Holiday; use entity::gateway::{EntityGateway, InMemoryGateway}; @@ -363,13 +363,13 @@ fn main() { let ship_state = ShipServerStateBuilder::default() .name("US/Sona-Nyl".into()) .ip(Ipv4Addr::new(127,0,0,1)) - .port(elseware::ship::ship::SHIP_PORT) + .port(ship_server::SHIP_PORT) .event(Holiday::Halloween) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); let ship_loop1 = async_std::task::spawn(async move { - networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT).await; + networking::mainloop::run_server(sub_ship_state, ship_server::SHIP_PORT).await; }); let sub_ship_state = ship_state.clone(); let inter_ship_loop1 = async_std::task::spawn(async move { @@ -379,13 +379,13 @@ fn main() { let ship_state = ShipServerStateBuilder::default() .name("EU/Dylath-Leen".into()) .ip(Ipv4Addr::new(127,0,0,1)) - .port(elseware::ship::ship::SHIP_PORT+2000) + .port(ship_server::SHIP_PORT+2000) .event(Holiday::Christmas) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); let ship_loop2 = async_std::task::spawn(async move { - networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT+2000).await; + networking::mainloop::run_server(sub_ship_state, ship_server::SHIP_PORT+2000).await; }); let sub_ship_state = ship_state.clone(); let inter_ship_loop2 = async_std::task::spawn(async move { @@ -395,12 +395,12 @@ fn main() { let ship_state = ShipServerStateBuilder::default() .name("JP/Thalarion".into()) .ip(Ipv4Addr::new(127,0,0,1)) - .port(elseware::ship::ship::SHIP_PORT+3000) + .port(ship_server::SHIP_PORT+3000) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); let ship_loop3 = async_std::task::spawn(async move { - networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT+3000).await; + networking::mainloop::run_server(sub_ship_state, ship_server::SHIP_PORT+3000).await; }); let sub_ship_state = ship_state.clone(); let inter_ship_loop3 = async_std::task::spawn(async move { diff --git a/src/bin/ship.rs b/src/bin/ship.rs index cfa50ed..b664bda 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -1,6 +1,6 @@ use log::info; use entity::gateway::postgres::PostgresGateway; -use elseware::ship::ship::ShipServerStateBuilder; +use ship_server::ShipServerStateBuilder; use networking::interserver::AuthToken; fn main() { @@ -40,7 +40,7 @@ fn main() { let ship_state = ShipServerStateBuilder::default() .name(ship_name) .ip(ip) - .port(elseware::ship::ship::SHIP_PORT) + .port(ship_server::SHIP_PORT) .gateway(entity_gateway) .auth_token(AuthToken(shipgate_token)) .build(); @@ -49,7 +49,7 @@ fn main() { let sub_ship_state = ship_state.clone(); let ship_loop = async_std::task::spawn(async move { - networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT).await; + networking::mainloop::run_server(sub_ship_state, ship_server::SHIP_PORT).await; }); let inter_ship_loop = async_std::task::spawn(async move { networking::mainloop::run_interserver_connect(ship_state, shipgate_ip, login_server::login::COMMUNICATION_PORT).await; diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index 3b52841..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow(clippy::type_complexity)] -#![allow(incomplete_features)] -#![feature(inline_const)] -#![feature(extract_if)] -#![feature(try_blocks)] -#![feature(test)] -#![feature(error_generic_member_access)] - -extern crate test; - -//pub mod common; -//pub mod entity; -//pub mod patch; -//pub mod login; -pub mod ship; diff --git a/src/ship/mod.rs b/src/ship/mod.rs deleted file mode 100644 index cf2a804..0000000 --- a/src/ship/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[allow(clippy::module_inception)] -pub mod ship; -pub mod packet; -pub mod chatcommand; diff --git a/src/ship/packet/handler/mod.rs b/src/ship/packet/handler/mod.rs deleted file mode 100644 index c921d28..0000000 --- a/src/ship/packet/handler/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod auth; -pub mod communication; -pub mod direct_message; -pub mod lobby; -pub mod message; -pub mod room; -pub mod settings; -pub mod quest; -pub mod ship; -pub mod trade; diff --git a/src/ship/packet/mod.rs b/src/ship/packet/mod.rs deleted file mode 100644 index 9b5f908..0000000 --- a/src/ship/packet/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -//pub mod builder; -pub mod handler; diff --git a/tests/common.rs b/tests/common.rs index eb21187..ebab507 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -5,7 +5,7 @@ use entity::gateway::EntityGateway; use entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity}; use entity::character::{CharacterEntity, NewCharacterEntity, SectionID}; use entity::item::{Meseta, BankIdentifier}; -use elseware::ship::ship::{ShipServerState, ShipServerStateBuilder, RecvShipPacket}; +use ship_server::{ShipServerState, ShipServerStateBuilder, RecvShipPacket}; use maps::room::{RoomMode, Difficulty, Episode}; use maps::area::MapArea; use maps::maps::null_free_roam_maps; diff --git a/tests/test_bank.rs b/tests/test_bank.rs index 9211f97..7f825af 100644 --- a/tests/test_bank.rs +++ b/tests/test_bank.rs @@ -2,7 +2,7 @@ use std::collections::BTreeSet; use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::{RecvShipPacket, SendShipPacket}; +use ship_server::{RecvShipPacket, SendShipPacket}; use shops::StandardItemShops; use libpso::packet::ship::*; diff --git a/tests/test_character.rs b/tests/test_character.rs index 3a9cc64..237ded9 100644 --- a/tests/test_character.rs +++ b/tests/test_character.rs @@ -1,6 +1,6 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::ship::ship::RecvShipPacket; +use ship_server::RecvShipPacket; use libpso::character::settings::{DEFAULT_KEYBOARD_CONFIG1, DEFAULT_KEYBOARD_CONFIG4}; use libpso::packet::ship::*; diff --git a/tests/test_exp_gain.rs b/tests/test_exp_gain.rs index da30c8a..db71ec9 100644 --- a/tests/test_exp_gain.rs +++ b/tests/test_exp_gain.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use stats::leveltable::CharacterLevelTable; -use elseware::ship::ship::{SendShipPacket, RecvShipPacket}; +use ship_server::{SendShipPacket, RecvShipPacket}; use maps::variant::{MapVariant, MapVariantMode}; use maps::maps::Maps; use maps::area::MapArea; diff --git a/tests/test_item_actions.rs b/tests/test_item_actions.rs index beef459..1237063 100644 --- a/tests/test_item_actions.rs +++ b/tests/test_item_actions.rs @@ -1,6 +1,6 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::ship::ship::RecvShipPacket; +use ship_server::RecvShipPacket; use entity::item; use libpso::packet::ship::*; diff --git a/tests/test_item_drop.rs b/tests/test_item_drop.rs index bcf4165..91f179b 100644 --- a/tests/test_item_drop.rs +++ b/tests/test_item_drop.rs @@ -1,6 +1,6 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::InMemoryGateway; -use elseware::ship::ship::{SendShipPacket, RecvShipPacket}; +use ship_server::{SendShipPacket, RecvShipPacket}; use maps::monster::MonsterType; use drops::{StandardDropTable, MonsterDropStats, MonsterDropType}; use drops::rare_drop_table::{RareDropTable, RareDropRate, RareDropItem}; diff --git a/tests/test_item_id.rs b/tests/test_item_id.rs index 01ec5d2..3302806 100644 --- a/tests/test_item_id.rs +++ b/tests/test_item_id.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::RecvShipPacket; +use ship_server::RecvShipPacket; use libpso::packet::ship::*; use libpso::packet::messages::*; diff --git a/tests/test_item_pickup.rs b/tests/test_item_pickup.rs index 82dd777..ccef78a 100644 --- a/tests/test_item_pickup.rs +++ b/tests/test_item_pickup.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::RecvShipPacket; +use ship_server::RecvShipPacket; use libpso::packet::ship::*; use libpso::packet::messages::*; diff --git a/tests/test_item_use.rs b/tests/test_item_use.rs index d4117f7..274a344 100644 --- a/tests/test_item_use.rs +++ b/tests/test_item_use.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::RecvShipPacket; +use ship_server::RecvShipPacket; use entity::character::TechLevel; use libpso::packet::ship::*; diff --git a/tests/test_mags.rs b/tests/test_mags.rs index d55a269..8ffc6a9 100644 --- a/tests/test_mags.rs +++ b/tests/test_mags.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::RecvShipPacket; +use ship_server::RecvShipPacket; use entity::character::{CharacterClass, SectionID}; use libpso::packet::ship::*; diff --git a/tests/test_rooms.rs b/tests/test_rooms.rs index 3d073e4..5e65574 100644 --- a/tests/test_rooms.rs +++ b/tests/test_rooms.rs @@ -1,6 +1,6 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; -use elseware::ship::ship::{RecvShipPacket, SendShipPacket}; +use ship_server::{RecvShipPacket, SendShipPacket}; use libpso::packet::ship::*; //use libpso::packet::messages::*; diff --git a/tests/test_shops.rs b/tests/test_shops.rs index 3e2dc02..59540b7 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -1,7 +1,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::{RecvShipPacket, SendShipPacket}; +use ship_server::{RecvShipPacket, SendShipPacket}; use maps::room::Difficulty; use items::state::ItemStateError; use shops::StandardItemShops; diff --git a/tests/test_trade.rs b/tests/test_trade.rs index 93f1463..8266892 100644 --- a/tests/test_trade.rs +++ b/tests/test_trade.rs @@ -2,9 +2,9 @@ use std::convert::TryInto; use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; -use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; +use ship_server::{ShipServerState, RecvShipPacket, SendShipPacket}; use entity::item::{Meseta, ItemEntity, InventoryItemEntity}; -use elseware::ship::packet::handler::trade::TradeError; +use ship_server::trade::TradeError; use libpso::packet::ship::*; use libpso::packet::messages::*; -- 2.36.0 From 0d710fad45124367236ede383bce36fddb68d3dc Mon Sep 17 00:00:00 2001 From: jake Date: Mon, 13 Nov 2023 23:41:48 -0700 Subject: [PATCH 56/58] move all the crate dirs back under src/ --- Cargo.toml | 89 +++++++++---------- {client => src/client}/Cargo.toml | 0 {client => src/client}/src/lib.rs | 0 {drops => src/drops}/Cargo.toml | 0 {drops => src/drops}/src/box_drop_table.rs | 0 {drops => src/drops}/src/generic_armor.rs | 0 {drops => src/drops}/src/generic_shield.rs | 0 {drops => src/drops}/src/generic_unit.rs | 0 {drops => src/drops}/src/generic_weapon.rs | 0 {drops => src/drops}/src/lib.rs | 0 {drops => src/drops}/src/rare_drop_table.rs | 0 {drops => src/drops}/src/tech_table.rs | 0 {drops => src/drops}/src/tool_table.rs | 0 {entity => src/entity}/Cargo.toml | 0 {entity => src/entity}/src/account.rs | 0 {entity => src/entity}/src/character.rs | 0 .../entity}/src/gateway/entitygateway.rs | 0 .../entity}/src/gateway/inmemory.rs | 0 {entity => src/entity}/src/gateway/mod.rs | 0 .../postgres/migrations/V0001__initial.sql | 0 .../postgres/migrations/V0002__equips.sql | 0 .../postgres/migrations/V0003__item_notes.sql | 0 .../postgres/migrations/V0004__meseta.sql | 0 .../postgres/migrations/V0005__trade.sql | 0 .../postgres/migrations/V0006__playtime.sql | 0 .../migrations/V0007__player_keyconfig.sql | 0 .../migrations/V0008__playtime_not_null.sql | 0 .../migrations/V0009__no_player_keyconfig.sql | 0 .../V0010__char_create_timestamp.sql | 0 .../migrations/V0011__shared_bank.sql | 0 .../postgres/migrations/V0012__room.sql | 0 .../postgres/migrations/V0013__room2.sql | 0 .../src/gateway/postgres/migrations/mod.rs | 0 .../entity}/src/gateway/postgres/mod.rs | 0 .../entity}/src/gateway/postgres/models.rs | 0 .../entity}/src/gateway/postgres/postgres.rs | 0 {entity => src/entity}/src/item/armor.rs | 0 {entity => src/entity}/src/item/esweapon.rs | 0 {entity => src/entity}/src/item/mag.rs | 0 {entity => src/entity}/src/item/mod.rs | 0 {entity => src/entity}/src/item/shield.rs | 0 {entity => src/entity}/src/item/tech.rs | 0 {entity => src/entity}/src/item/tool.rs | 0 {entity => src/entity}/src/item/unit.rs | 0 {entity => src/entity}/src/item/weapon.rs | 0 {entity => src/entity}/src/lib.rs | 0 {entity => src/entity}/src/room.rs | 0 {entity => src/entity}/src/team.rs | 0 {items => src/items}/Cargo.toml | 0 {items => src/items}/src/actions.rs | 0 {items => src/items}/src/apply_item.rs | 0 {items => src/items}/src/bank.rs | 0 {items => src/items}/src/floor.rs | 0 {items => src/items}/src/inventory.rs | 0 {items => src/items}/src/itemstateaction.rs | 0 {items => src/items}/src/lib.rs | 0 {items => src/items}/src/manager.rs | 0 {items => src/items}/src/state.rs | 0 {items => src/items}/src/tasks.rs | 0 {items => src/items}/src/trade.rs | 0 {location => src/location}/Cargo.toml | 0 {location => src/location}/src/lib.rs | 0 {login_server => src/login_server}/Cargo.toml | 0 .../login_server}/src/character.rs | 0 {login_server => src/login_server}/src/lib.rs | 0 .../login_server}/src/login.rs | 0 {maps => src/maps}/Cargo.toml | 0 {maps => src/maps}/src/area.rs | 0 {maps => src/maps}/src/enemy.rs | 0 {maps => src/maps}/src/lib.rs | 0 {maps => src/maps}/src/maps.rs | 0 {maps => src/maps}/src/monster.rs | 0 {maps => src/maps}/src/object.rs | 0 {maps => src/maps}/src/room.rs | 0 {maps => src/maps}/src/variant.rs | 0 {networking => src/networking}/Cargo.toml | 0 .../networking}/src/cipherkeys.rs | 0 .../networking}/src/interserver.rs | 0 {networking => src/networking}/src/lib.rs | 0 .../networking}/src/mainloop/client.rs | 0 .../networking}/src/mainloop/interserver.rs | 0 .../networking}/src/mainloop/mod.rs | 0 .../networking}/src/serverstate.rs | 0 {patch_server => src/patch_server}/Cargo.toml | 0 {patch_server => src/patch_server}/src/lib.rs | 0 {pktbuilder => src/pktbuilder}/Cargo.toml | 0 .../pktbuilder}/src/character.rs | 0 {pktbuilder => src/pktbuilder}/src/lib.rs | 0 {pktbuilder => src/pktbuilder}/src/lobby.rs | 0 {pktbuilder => src/pktbuilder}/src/message.rs | 0 {pktbuilder => src/pktbuilder}/src/quest.rs | 0 {pktbuilder => src/pktbuilder}/src/room.rs | 0 {pktbuilder => src/pktbuilder}/src/ship.rs | 0 {pktbuilder => src/pktbuilder}/src/team.rs | 0 {pktbuilder => src/pktbuilder}/src/trade.rs | 0 {quests => src/quests}/Cargo.toml | 0 {quests => src/quests}/src/lib.rs | 0 {room => src/room}/Cargo.toml | 0 {room => src/room}/src/lib.rs | 0 {ship_server => src/ship_server}/Cargo.toml | 0 {ship_server => src/ship_server}/src/auth.rs | 0 .../ship_server}/src/chatcommand.rs | 0 .../ship_server}/src/communication.rs | 0 .../ship_server}/src/direct_message.rs | 0 {ship_server => src/ship_server}/src/lib.rs | 0 {ship_server => src/ship_server}/src/lobby.rs | 0 .../ship_server}/src/message.rs | 0 {ship_server => src/ship_server}/src/quest.rs | 0 {ship_server => src/ship_server}/src/room.rs | 0 .../ship_server}/src/settings.rs | 0 {ship_server => src/ship_server}/src/ship.rs | 0 {ship_server => src/ship_server}/src/trade.rs | 0 {shops => src/shops}/Cargo.toml | 0 {shops => src/shops}/src/armor.rs | 0 {shops => src/shops}/src/lib.rs | 0 {shops => src/shops}/src/tool.rs | 0 {shops => src/shops}/src/weapon.rs | 0 {stats => src/stats}/Cargo.toml | 0 {stats => src/stats}/src/items.rs | 0 {stats => src/stats}/src/leveltable.rs | 0 {stats => src/stats}/src/lib.rs | 0 {trade => src/trade}/Cargo.toml | 0 {trade => src/trade}/src/lib.rs | 0 123 files changed, 40 insertions(+), 49 deletions(-) rename {client => src/client}/Cargo.toml (100%) rename {client => src/client}/src/lib.rs (100%) rename {drops => src/drops}/Cargo.toml (100%) rename {drops => src/drops}/src/box_drop_table.rs (100%) rename {drops => src/drops}/src/generic_armor.rs (100%) rename {drops => src/drops}/src/generic_shield.rs (100%) rename {drops => src/drops}/src/generic_unit.rs (100%) rename {drops => src/drops}/src/generic_weapon.rs (100%) rename {drops => src/drops}/src/lib.rs (100%) rename {drops => src/drops}/src/rare_drop_table.rs (100%) rename {drops => src/drops}/src/tech_table.rs (100%) rename {drops => src/drops}/src/tool_table.rs (100%) rename {entity => src/entity}/Cargo.toml (100%) rename {entity => src/entity}/src/account.rs (100%) rename {entity => src/entity}/src/character.rs (100%) rename {entity => src/entity}/src/gateway/entitygateway.rs (100%) rename {entity => src/entity}/src/gateway/inmemory.rs (100%) rename {entity => src/entity}/src/gateway/mod.rs (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0001__initial.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0002__equips.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0003__item_notes.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0004__meseta.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0005__trade.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0006__playtime.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0007__player_keyconfig.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0008__playtime_not_null.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0009__no_player_keyconfig.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0010__char_create_timestamp.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0011__shared_bank.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0012__room.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/V0013__room2.sql (100%) rename {entity => src/entity}/src/gateway/postgres/migrations/mod.rs (100%) rename {entity => src/entity}/src/gateway/postgres/mod.rs (100%) rename {entity => src/entity}/src/gateway/postgres/models.rs (100%) rename {entity => src/entity}/src/gateway/postgres/postgres.rs (100%) rename {entity => src/entity}/src/item/armor.rs (100%) rename {entity => src/entity}/src/item/esweapon.rs (100%) rename {entity => src/entity}/src/item/mag.rs (100%) rename {entity => src/entity}/src/item/mod.rs (100%) rename {entity => src/entity}/src/item/shield.rs (100%) rename {entity => src/entity}/src/item/tech.rs (100%) rename {entity => src/entity}/src/item/tool.rs (100%) rename {entity => src/entity}/src/item/unit.rs (100%) rename {entity => src/entity}/src/item/weapon.rs (100%) rename {entity => src/entity}/src/lib.rs (100%) rename {entity => src/entity}/src/room.rs (100%) rename {entity => src/entity}/src/team.rs (100%) rename {items => src/items}/Cargo.toml (100%) rename {items => src/items}/src/actions.rs (100%) rename {items => src/items}/src/apply_item.rs (100%) rename {items => src/items}/src/bank.rs (100%) rename {items => src/items}/src/floor.rs (100%) rename {items => src/items}/src/inventory.rs (100%) rename {items => src/items}/src/itemstateaction.rs (100%) rename {items => src/items}/src/lib.rs (100%) rename {items => src/items}/src/manager.rs (100%) rename {items => src/items}/src/state.rs (100%) rename {items => src/items}/src/tasks.rs (100%) rename {items => src/items}/src/trade.rs (100%) rename {location => src/location}/Cargo.toml (100%) rename {location => src/location}/src/lib.rs (100%) rename {login_server => src/login_server}/Cargo.toml (100%) rename {login_server => src/login_server}/src/character.rs (100%) rename {login_server => src/login_server}/src/lib.rs (100%) rename {login_server => src/login_server}/src/login.rs (100%) rename {maps => src/maps}/Cargo.toml (100%) rename {maps => src/maps}/src/area.rs (100%) rename {maps => src/maps}/src/enemy.rs (100%) rename {maps => src/maps}/src/lib.rs (100%) rename {maps => src/maps}/src/maps.rs (100%) rename {maps => src/maps}/src/monster.rs (100%) rename {maps => src/maps}/src/object.rs (100%) rename {maps => src/maps}/src/room.rs (100%) rename {maps => src/maps}/src/variant.rs (100%) rename {networking => src/networking}/Cargo.toml (100%) rename {networking => src/networking}/src/cipherkeys.rs (100%) rename {networking => src/networking}/src/interserver.rs (100%) rename {networking => src/networking}/src/lib.rs (100%) rename {networking => src/networking}/src/mainloop/client.rs (100%) rename {networking => src/networking}/src/mainloop/interserver.rs (100%) rename {networking => src/networking}/src/mainloop/mod.rs (100%) rename {networking => src/networking}/src/serverstate.rs (100%) rename {patch_server => src/patch_server}/Cargo.toml (100%) rename {patch_server => src/patch_server}/src/lib.rs (100%) rename {pktbuilder => src/pktbuilder}/Cargo.toml (100%) rename {pktbuilder => src/pktbuilder}/src/character.rs (100%) rename {pktbuilder => src/pktbuilder}/src/lib.rs (100%) rename {pktbuilder => src/pktbuilder}/src/lobby.rs (100%) rename {pktbuilder => src/pktbuilder}/src/message.rs (100%) rename {pktbuilder => src/pktbuilder}/src/quest.rs (100%) rename {pktbuilder => src/pktbuilder}/src/room.rs (100%) rename {pktbuilder => src/pktbuilder}/src/ship.rs (100%) rename {pktbuilder => src/pktbuilder}/src/team.rs (100%) rename {pktbuilder => src/pktbuilder}/src/trade.rs (100%) rename {quests => src/quests}/Cargo.toml (100%) rename {quests => src/quests}/src/lib.rs (100%) rename {room => src/room}/Cargo.toml (100%) rename {room => src/room}/src/lib.rs (100%) rename {ship_server => src/ship_server}/Cargo.toml (100%) rename {ship_server => src/ship_server}/src/auth.rs (100%) rename {ship_server => src/ship_server}/src/chatcommand.rs (100%) rename {ship_server => src/ship_server}/src/communication.rs (100%) rename {ship_server => src/ship_server}/src/direct_message.rs (100%) rename {ship_server => src/ship_server}/src/lib.rs (100%) rename {ship_server => src/ship_server}/src/lobby.rs (100%) rename {ship_server => src/ship_server}/src/message.rs (100%) rename {ship_server => src/ship_server}/src/quest.rs (100%) rename {ship_server => src/ship_server}/src/room.rs (100%) rename {ship_server => src/ship_server}/src/settings.rs (100%) rename {ship_server => src/ship_server}/src/ship.rs (100%) rename {ship_server => src/ship_server}/src/trade.rs (100%) rename {shops => src/shops}/Cargo.toml (100%) rename {shops => src/shops}/src/armor.rs (100%) rename {shops => src/shops}/src/lib.rs (100%) rename {shops => src/shops}/src/tool.rs (100%) rename {shops => src/shops}/src/weapon.rs (100%) rename {stats => src/stats}/Cargo.toml (100%) rename {stats => src/stats}/src/items.rs (100%) rename {stats => src/stats}/src/leveltable.rs (100%) rename {stats => src/stats}/src/lib.rs (100%) rename {trade => src/trade}/Cargo.toml (100%) rename {trade => src/trade}/src/lib.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index a514c54..32363b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,41 +6,41 @@ edition = "2021" [workspace] members = [ - "client", - "drops", - "entity", - "items", - "location", - "maps", - "networking", - "pktbuilder", - "quests", - "room", - "shops", - "stats", - "trade", - "patch_server", - "login_server", - "ship_server", + "src/client", + "src/drops", + "src/entity", + "src/items", + "src/location", + "src/maps", + "src/networking", + "src/pktbuilder", + "src/quests", + "src/room", + "src/shops", + "src/stats", + "src/trade", + "src/patch_server", + "src/login_server", + "src/ship_server", ] [workspace.dependencies] -entity = { path = "./entity" } -maps = { path = "./maps" } -networking = { path = "./networking" } -shops = { path = "./shops" } -stats = { path = "./stats" } -items = { path = "./items" } -pktbuilder = { path = "./pktbuilder" } -quests = { path = "./quests" } -location = { path = "./location" } -client = { path = "./client" } -drops = { path = "./drops" } -trade = { path = "./trade" } -room = { path = "./room" } -patch_server = { path = "./patch_server" } -login_server = { path = "./login_server" } -ship_server = { path = "./ship_server" } +entity = { path = "./src/entity" } +maps = { path = "./src/maps" } +networking = { path = "./src/networking" } +shops = { path = "./src/shops" } +stats = { path = "./src/stats" } +items = { path = "./src/items" } +pktbuilder = { path = "./src/pktbuilder" } +quests = { path = "./src/quests" } +location = { path = "./src/location" } +client = { path = "./src/client" } +drops = { path = "./src/drops" } +trade = { path = "./src/trade" } +room = { path = "./src/room" } +patch_server = { path = "./src/patch_server" } +login_server = { path = "./src/login_server" } +ship_server = { path = "./src/ship_server" } libpso = { git = "http://git.sharnoth.com/jake/libpso" } @@ -76,32 +76,23 @@ anyhow = { version = "1.0.68", features = ["backtrace"] } entity = { workspace = true } maps = { workspace = true } networking = { workspace = true } -shops = { workspace = true } -stats = { workspace = true } -items = { workspace = true } -pktbuilder = { workspace = true } -quests = { workspace = true } -location = { workspace = true } -client = { workspace = true } -drops = { workspace = true } -trade = { workspace = true } -room = { workspace = true } patch_server = { workspace = true } login_server = { workspace = true } ship_server = { workspace = true } libpso = { workspace = true } -anyhow = { workspace = true } async-std = { workspace = true } -async-trait = { workspace = true } bcrypt = { workspace = true } chrono = { workspace = true } -crc = { workspace = true } fern = { workspace = true } futures = { workspace = true } log = { workspace = true } -rand = { workspace = true } -ron = { workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } \ No newline at end of file + +[dev-dependencies] +drops = { workspace = true } +shops = { workspace = true } +items = { workspace = true } +quests = { workspace = true } +stats = { workspace = true } +async-trait = { workspace = true } \ No newline at end of file diff --git a/client/Cargo.toml b/src/client/Cargo.toml similarity index 100% rename from client/Cargo.toml rename to src/client/Cargo.toml diff --git a/client/src/lib.rs b/src/client/src/lib.rs similarity index 100% rename from client/src/lib.rs rename to src/client/src/lib.rs diff --git a/drops/Cargo.toml b/src/drops/Cargo.toml similarity index 100% rename from drops/Cargo.toml rename to src/drops/Cargo.toml diff --git a/drops/src/box_drop_table.rs b/src/drops/src/box_drop_table.rs similarity index 100% rename from drops/src/box_drop_table.rs rename to src/drops/src/box_drop_table.rs diff --git a/drops/src/generic_armor.rs b/src/drops/src/generic_armor.rs similarity index 100% rename from drops/src/generic_armor.rs rename to src/drops/src/generic_armor.rs diff --git a/drops/src/generic_shield.rs b/src/drops/src/generic_shield.rs similarity index 100% rename from drops/src/generic_shield.rs rename to src/drops/src/generic_shield.rs diff --git a/drops/src/generic_unit.rs b/src/drops/src/generic_unit.rs similarity index 100% rename from drops/src/generic_unit.rs rename to src/drops/src/generic_unit.rs diff --git a/drops/src/generic_weapon.rs b/src/drops/src/generic_weapon.rs similarity index 100% rename from drops/src/generic_weapon.rs rename to src/drops/src/generic_weapon.rs diff --git a/drops/src/lib.rs b/src/drops/src/lib.rs similarity index 100% rename from drops/src/lib.rs rename to src/drops/src/lib.rs diff --git a/drops/src/rare_drop_table.rs b/src/drops/src/rare_drop_table.rs similarity index 100% rename from drops/src/rare_drop_table.rs rename to src/drops/src/rare_drop_table.rs diff --git a/drops/src/tech_table.rs b/src/drops/src/tech_table.rs similarity index 100% rename from drops/src/tech_table.rs rename to src/drops/src/tech_table.rs diff --git a/drops/src/tool_table.rs b/src/drops/src/tool_table.rs similarity index 100% rename from drops/src/tool_table.rs rename to src/drops/src/tool_table.rs diff --git a/entity/Cargo.toml b/src/entity/Cargo.toml similarity index 100% rename from entity/Cargo.toml rename to src/entity/Cargo.toml diff --git a/entity/src/account.rs b/src/entity/src/account.rs similarity index 100% rename from entity/src/account.rs rename to src/entity/src/account.rs diff --git a/entity/src/character.rs b/src/entity/src/character.rs similarity index 100% rename from entity/src/character.rs rename to src/entity/src/character.rs diff --git a/entity/src/gateway/entitygateway.rs b/src/entity/src/gateway/entitygateway.rs similarity index 100% rename from entity/src/gateway/entitygateway.rs rename to src/entity/src/gateway/entitygateway.rs diff --git a/entity/src/gateway/inmemory.rs b/src/entity/src/gateway/inmemory.rs similarity index 100% rename from entity/src/gateway/inmemory.rs rename to src/entity/src/gateway/inmemory.rs diff --git a/entity/src/gateway/mod.rs b/src/entity/src/gateway/mod.rs similarity index 100% rename from entity/src/gateway/mod.rs rename to src/entity/src/gateway/mod.rs diff --git a/entity/src/gateway/postgres/migrations/V0001__initial.sql b/src/entity/src/gateway/postgres/migrations/V0001__initial.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0001__initial.sql rename to src/entity/src/gateway/postgres/migrations/V0001__initial.sql diff --git a/entity/src/gateway/postgres/migrations/V0002__equips.sql b/src/entity/src/gateway/postgres/migrations/V0002__equips.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0002__equips.sql rename to src/entity/src/gateway/postgres/migrations/V0002__equips.sql diff --git a/entity/src/gateway/postgres/migrations/V0003__item_notes.sql b/src/entity/src/gateway/postgres/migrations/V0003__item_notes.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0003__item_notes.sql rename to src/entity/src/gateway/postgres/migrations/V0003__item_notes.sql diff --git a/entity/src/gateway/postgres/migrations/V0004__meseta.sql b/src/entity/src/gateway/postgres/migrations/V0004__meseta.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0004__meseta.sql rename to src/entity/src/gateway/postgres/migrations/V0004__meseta.sql diff --git a/entity/src/gateway/postgres/migrations/V0005__trade.sql b/src/entity/src/gateway/postgres/migrations/V0005__trade.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0005__trade.sql rename to src/entity/src/gateway/postgres/migrations/V0005__trade.sql diff --git a/entity/src/gateway/postgres/migrations/V0006__playtime.sql b/src/entity/src/gateway/postgres/migrations/V0006__playtime.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0006__playtime.sql rename to src/entity/src/gateway/postgres/migrations/V0006__playtime.sql diff --git a/entity/src/gateway/postgres/migrations/V0007__player_keyconfig.sql b/src/entity/src/gateway/postgres/migrations/V0007__player_keyconfig.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0007__player_keyconfig.sql rename to src/entity/src/gateway/postgres/migrations/V0007__player_keyconfig.sql diff --git a/entity/src/gateway/postgres/migrations/V0008__playtime_not_null.sql b/src/entity/src/gateway/postgres/migrations/V0008__playtime_not_null.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0008__playtime_not_null.sql rename to src/entity/src/gateway/postgres/migrations/V0008__playtime_not_null.sql diff --git a/entity/src/gateway/postgres/migrations/V0009__no_player_keyconfig.sql b/src/entity/src/gateway/postgres/migrations/V0009__no_player_keyconfig.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0009__no_player_keyconfig.sql rename to src/entity/src/gateway/postgres/migrations/V0009__no_player_keyconfig.sql diff --git a/entity/src/gateway/postgres/migrations/V0010__char_create_timestamp.sql b/src/entity/src/gateway/postgres/migrations/V0010__char_create_timestamp.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0010__char_create_timestamp.sql rename to src/entity/src/gateway/postgres/migrations/V0010__char_create_timestamp.sql diff --git a/entity/src/gateway/postgres/migrations/V0011__shared_bank.sql b/src/entity/src/gateway/postgres/migrations/V0011__shared_bank.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0011__shared_bank.sql rename to src/entity/src/gateway/postgres/migrations/V0011__shared_bank.sql diff --git a/entity/src/gateway/postgres/migrations/V0012__room.sql b/src/entity/src/gateway/postgres/migrations/V0012__room.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0012__room.sql rename to src/entity/src/gateway/postgres/migrations/V0012__room.sql diff --git a/entity/src/gateway/postgres/migrations/V0013__room2.sql b/src/entity/src/gateway/postgres/migrations/V0013__room2.sql similarity index 100% rename from entity/src/gateway/postgres/migrations/V0013__room2.sql rename to src/entity/src/gateway/postgres/migrations/V0013__room2.sql diff --git a/entity/src/gateway/postgres/migrations/mod.rs b/src/entity/src/gateway/postgres/migrations/mod.rs similarity index 100% rename from entity/src/gateway/postgres/migrations/mod.rs rename to src/entity/src/gateway/postgres/migrations/mod.rs diff --git a/entity/src/gateway/postgres/mod.rs b/src/entity/src/gateway/postgres/mod.rs similarity index 100% rename from entity/src/gateway/postgres/mod.rs rename to src/entity/src/gateway/postgres/mod.rs diff --git a/entity/src/gateway/postgres/models.rs b/src/entity/src/gateway/postgres/models.rs similarity index 100% rename from entity/src/gateway/postgres/models.rs rename to src/entity/src/gateway/postgres/models.rs diff --git a/entity/src/gateway/postgres/postgres.rs b/src/entity/src/gateway/postgres/postgres.rs similarity index 100% rename from entity/src/gateway/postgres/postgres.rs rename to src/entity/src/gateway/postgres/postgres.rs diff --git a/entity/src/item/armor.rs b/src/entity/src/item/armor.rs similarity index 100% rename from entity/src/item/armor.rs rename to src/entity/src/item/armor.rs diff --git a/entity/src/item/esweapon.rs b/src/entity/src/item/esweapon.rs similarity index 100% rename from entity/src/item/esweapon.rs rename to src/entity/src/item/esweapon.rs diff --git a/entity/src/item/mag.rs b/src/entity/src/item/mag.rs similarity index 100% rename from entity/src/item/mag.rs rename to src/entity/src/item/mag.rs diff --git a/entity/src/item/mod.rs b/src/entity/src/item/mod.rs similarity index 100% rename from entity/src/item/mod.rs rename to src/entity/src/item/mod.rs diff --git a/entity/src/item/shield.rs b/src/entity/src/item/shield.rs similarity index 100% rename from entity/src/item/shield.rs rename to src/entity/src/item/shield.rs diff --git a/entity/src/item/tech.rs b/src/entity/src/item/tech.rs similarity index 100% rename from entity/src/item/tech.rs rename to src/entity/src/item/tech.rs diff --git a/entity/src/item/tool.rs b/src/entity/src/item/tool.rs similarity index 100% rename from entity/src/item/tool.rs rename to src/entity/src/item/tool.rs diff --git a/entity/src/item/unit.rs b/src/entity/src/item/unit.rs similarity index 100% rename from entity/src/item/unit.rs rename to src/entity/src/item/unit.rs diff --git a/entity/src/item/weapon.rs b/src/entity/src/item/weapon.rs similarity index 100% rename from entity/src/item/weapon.rs rename to src/entity/src/item/weapon.rs diff --git a/entity/src/lib.rs b/src/entity/src/lib.rs similarity index 100% rename from entity/src/lib.rs rename to src/entity/src/lib.rs diff --git a/entity/src/room.rs b/src/entity/src/room.rs similarity index 100% rename from entity/src/room.rs rename to src/entity/src/room.rs diff --git a/entity/src/team.rs b/src/entity/src/team.rs similarity index 100% rename from entity/src/team.rs rename to src/entity/src/team.rs diff --git a/items/Cargo.toml b/src/items/Cargo.toml similarity index 100% rename from items/Cargo.toml rename to src/items/Cargo.toml diff --git a/items/src/actions.rs b/src/items/src/actions.rs similarity index 100% rename from items/src/actions.rs rename to src/items/src/actions.rs diff --git a/items/src/apply_item.rs b/src/items/src/apply_item.rs similarity index 100% rename from items/src/apply_item.rs rename to src/items/src/apply_item.rs diff --git a/items/src/bank.rs b/src/items/src/bank.rs similarity index 100% rename from items/src/bank.rs rename to src/items/src/bank.rs diff --git a/items/src/floor.rs b/src/items/src/floor.rs similarity index 100% rename from items/src/floor.rs rename to src/items/src/floor.rs diff --git a/items/src/inventory.rs b/src/items/src/inventory.rs similarity index 100% rename from items/src/inventory.rs rename to src/items/src/inventory.rs diff --git a/items/src/itemstateaction.rs b/src/items/src/itemstateaction.rs similarity index 100% rename from items/src/itemstateaction.rs rename to src/items/src/itemstateaction.rs diff --git a/items/src/lib.rs b/src/items/src/lib.rs similarity index 100% rename from items/src/lib.rs rename to src/items/src/lib.rs diff --git a/items/src/manager.rs b/src/items/src/manager.rs similarity index 100% rename from items/src/manager.rs rename to src/items/src/manager.rs diff --git a/items/src/state.rs b/src/items/src/state.rs similarity index 100% rename from items/src/state.rs rename to src/items/src/state.rs diff --git a/items/src/tasks.rs b/src/items/src/tasks.rs similarity index 100% rename from items/src/tasks.rs rename to src/items/src/tasks.rs diff --git a/items/src/trade.rs b/src/items/src/trade.rs similarity index 100% rename from items/src/trade.rs rename to src/items/src/trade.rs diff --git a/location/Cargo.toml b/src/location/Cargo.toml similarity index 100% rename from location/Cargo.toml rename to src/location/Cargo.toml diff --git a/location/src/lib.rs b/src/location/src/lib.rs similarity index 100% rename from location/src/lib.rs rename to src/location/src/lib.rs diff --git a/login_server/Cargo.toml b/src/login_server/Cargo.toml similarity index 100% rename from login_server/Cargo.toml rename to src/login_server/Cargo.toml diff --git a/login_server/src/character.rs b/src/login_server/src/character.rs similarity index 100% rename from login_server/src/character.rs rename to src/login_server/src/character.rs diff --git a/login_server/src/lib.rs b/src/login_server/src/lib.rs similarity index 100% rename from login_server/src/lib.rs rename to src/login_server/src/lib.rs diff --git a/login_server/src/login.rs b/src/login_server/src/login.rs similarity index 100% rename from login_server/src/login.rs rename to src/login_server/src/login.rs diff --git a/maps/Cargo.toml b/src/maps/Cargo.toml similarity index 100% rename from maps/Cargo.toml rename to src/maps/Cargo.toml diff --git a/maps/src/area.rs b/src/maps/src/area.rs similarity index 100% rename from maps/src/area.rs rename to src/maps/src/area.rs diff --git a/maps/src/enemy.rs b/src/maps/src/enemy.rs similarity index 100% rename from maps/src/enemy.rs rename to src/maps/src/enemy.rs diff --git a/maps/src/lib.rs b/src/maps/src/lib.rs similarity index 100% rename from maps/src/lib.rs rename to src/maps/src/lib.rs diff --git a/maps/src/maps.rs b/src/maps/src/maps.rs similarity index 100% rename from maps/src/maps.rs rename to src/maps/src/maps.rs diff --git a/maps/src/monster.rs b/src/maps/src/monster.rs similarity index 100% rename from maps/src/monster.rs rename to src/maps/src/monster.rs diff --git a/maps/src/object.rs b/src/maps/src/object.rs similarity index 100% rename from maps/src/object.rs rename to src/maps/src/object.rs diff --git a/maps/src/room.rs b/src/maps/src/room.rs similarity index 100% rename from maps/src/room.rs rename to src/maps/src/room.rs diff --git a/maps/src/variant.rs b/src/maps/src/variant.rs similarity index 100% rename from maps/src/variant.rs rename to src/maps/src/variant.rs diff --git a/networking/Cargo.toml b/src/networking/Cargo.toml similarity index 100% rename from networking/Cargo.toml rename to src/networking/Cargo.toml diff --git a/networking/src/cipherkeys.rs b/src/networking/src/cipherkeys.rs similarity index 100% rename from networking/src/cipherkeys.rs rename to src/networking/src/cipherkeys.rs diff --git a/networking/src/interserver.rs b/src/networking/src/interserver.rs similarity index 100% rename from networking/src/interserver.rs rename to src/networking/src/interserver.rs diff --git a/networking/src/lib.rs b/src/networking/src/lib.rs similarity index 100% rename from networking/src/lib.rs rename to src/networking/src/lib.rs diff --git a/networking/src/mainloop/client.rs b/src/networking/src/mainloop/client.rs similarity index 100% rename from networking/src/mainloop/client.rs rename to src/networking/src/mainloop/client.rs diff --git a/networking/src/mainloop/interserver.rs b/src/networking/src/mainloop/interserver.rs similarity index 100% rename from networking/src/mainloop/interserver.rs rename to src/networking/src/mainloop/interserver.rs diff --git a/networking/src/mainloop/mod.rs b/src/networking/src/mainloop/mod.rs similarity index 100% rename from networking/src/mainloop/mod.rs rename to src/networking/src/mainloop/mod.rs diff --git a/networking/src/serverstate.rs b/src/networking/src/serverstate.rs similarity index 100% rename from networking/src/serverstate.rs rename to src/networking/src/serverstate.rs diff --git a/patch_server/Cargo.toml b/src/patch_server/Cargo.toml similarity index 100% rename from patch_server/Cargo.toml rename to src/patch_server/Cargo.toml diff --git a/patch_server/src/lib.rs b/src/patch_server/src/lib.rs similarity index 100% rename from patch_server/src/lib.rs rename to src/patch_server/src/lib.rs diff --git a/pktbuilder/Cargo.toml b/src/pktbuilder/Cargo.toml similarity index 100% rename from pktbuilder/Cargo.toml rename to src/pktbuilder/Cargo.toml diff --git a/pktbuilder/src/character.rs b/src/pktbuilder/src/character.rs similarity index 100% rename from pktbuilder/src/character.rs rename to src/pktbuilder/src/character.rs diff --git a/pktbuilder/src/lib.rs b/src/pktbuilder/src/lib.rs similarity index 100% rename from pktbuilder/src/lib.rs rename to src/pktbuilder/src/lib.rs diff --git a/pktbuilder/src/lobby.rs b/src/pktbuilder/src/lobby.rs similarity index 100% rename from pktbuilder/src/lobby.rs rename to src/pktbuilder/src/lobby.rs diff --git a/pktbuilder/src/message.rs b/src/pktbuilder/src/message.rs similarity index 100% rename from pktbuilder/src/message.rs rename to src/pktbuilder/src/message.rs diff --git a/pktbuilder/src/quest.rs b/src/pktbuilder/src/quest.rs similarity index 100% rename from pktbuilder/src/quest.rs rename to src/pktbuilder/src/quest.rs diff --git a/pktbuilder/src/room.rs b/src/pktbuilder/src/room.rs similarity index 100% rename from pktbuilder/src/room.rs rename to src/pktbuilder/src/room.rs diff --git a/pktbuilder/src/ship.rs b/src/pktbuilder/src/ship.rs similarity index 100% rename from pktbuilder/src/ship.rs rename to src/pktbuilder/src/ship.rs diff --git a/pktbuilder/src/team.rs b/src/pktbuilder/src/team.rs similarity index 100% rename from pktbuilder/src/team.rs rename to src/pktbuilder/src/team.rs diff --git a/pktbuilder/src/trade.rs b/src/pktbuilder/src/trade.rs similarity index 100% rename from pktbuilder/src/trade.rs rename to src/pktbuilder/src/trade.rs diff --git a/quests/Cargo.toml b/src/quests/Cargo.toml similarity index 100% rename from quests/Cargo.toml rename to src/quests/Cargo.toml diff --git a/quests/src/lib.rs b/src/quests/src/lib.rs similarity index 100% rename from quests/src/lib.rs rename to src/quests/src/lib.rs diff --git a/room/Cargo.toml b/src/room/Cargo.toml similarity index 100% rename from room/Cargo.toml rename to src/room/Cargo.toml diff --git a/room/src/lib.rs b/src/room/src/lib.rs similarity index 100% rename from room/src/lib.rs rename to src/room/src/lib.rs diff --git a/ship_server/Cargo.toml b/src/ship_server/Cargo.toml similarity index 100% rename from ship_server/Cargo.toml rename to src/ship_server/Cargo.toml diff --git a/ship_server/src/auth.rs b/src/ship_server/src/auth.rs similarity index 100% rename from ship_server/src/auth.rs rename to src/ship_server/src/auth.rs diff --git a/ship_server/src/chatcommand.rs b/src/ship_server/src/chatcommand.rs similarity index 100% rename from ship_server/src/chatcommand.rs rename to src/ship_server/src/chatcommand.rs diff --git a/ship_server/src/communication.rs b/src/ship_server/src/communication.rs similarity index 100% rename from ship_server/src/communication.rs rename to src/ship_server/src/communication.rs diff --git a/ship_server/src/direct_message.rs b/src/ship_server/src/direct_message.rs similarity index 100% rename from ship_server/src/direct_message.rs rename to src/ship_server/src/direct_message.rs diff --git a/ship_server/src/lib.rs b/src/ship_server/src/lib.rs similarity index 100% rename from ship_server/src/lib.rs rename to src/ship_server/src/lib.rs diff --git a/ship_server/src/lobby.rs b/src/ship_server/src/lobby.rs similarity index 100% rename from ship_server/src/lobby.rs rename to src/ship_server/src/lobby.rs diff --git a/ship_server/src/message.rs b/src/ship_server/src/message.rs similarity index 100% rename from ship_server/src/message.rs rename to src/ship_server/src/message.rs diff --git a/ship_server/src/quest.rs b/src/ship_server/src/quest.rs similarity index 100% rename from ship_server/src/quest.rs rename to src/ship_server/src/quest.rs diff --git a/ship_server/src/room.rs b/src/ship_server/src/room.rs similarity index 100% rename from ship_server/src/room.rs rename to src/ship_server/src/room.rs diff --git a/ship_server/src/settings.rs b/src/ship_server/src/settings.rs similarity index 100% rename from ship_server/src/settings.rs rename to src/ship_server/src/settings.rs diff --git a/ship_server/src/ship.rs b/src/ship_server/src/ship.rs similarity index 100% rename from ship_server/src/ship.rs rename to src/ship_server/src/ship.rs diff --git a/ship_server/src/trade.rs b/src/ship_server/src/trade.rs similarity index 100% rename from ship_server/src/trade.rs rename to src/ship_server/src/trade.rs diff --git a/shops/Cargo.toml b/src/shops/Cargo.toml similarity index 100% rename from shops/Cargo.toml rename to src/shops/Cargo.toml diff --git a/shops/src/armor.rs b/src/shops/src/armor.rs similarity index 100% rename from shops/src/armor.rs rename to src/shops/src/armor.rs diff --git a/shops/src/lib.rs b/src/shops/src/lib.rs similarity index 100% rename from shops/src/lib.rs rename to src/shops/src/lib.rs diff --git a/shops/src/tool.rs b/src/shops/src/tool.rs similarity index 100% rename from shops/src/tool.rs rename to src/shops/src/tool.rs diff --git a/shops/src/weapon.rs b/src/shops/src/weapon.rs similarity index 100% rename from shops/src/weapon.rs rename to src/shops/src/weapon.rs diff --git a/stats/Cargo.toml b/src/stats/Cargo.toml similarity index 100% rename from stats/Cargo.toml rename to src/stats/Cargo.toml diff --git a/stats/src/items.rs b/src/stats/src/items.rs similarity index 100% rename from stats/src/items.rs rename to src/stats/src/items.rs diff --git a/stats/src/leveltable.rs b/src/stats/src/leveltable.rs similarity index 100% rename from stats/src/leveltable.rs rename to src/stats/src/leveltable.rs diff --git a/stats/src/lib.rs b/src/stats/src/lib.rs similarity index 100% rename from stats/src/lib.rs rename to src/stats/src/lib.rs diff --git a/trade/Cargo.toml b/src/trade/Cargo.toml similarity index 100% rename from trade/Cargo.toml rename to src/trade/Cargo.toml diff --git a/trade/src/lib.rs b/src/trade/src/lib.rs similarity index 100% rename from trade/src/lib.rs rename to src/trade/src/lib.rs -- 2.36.0 From 0d9e2b8609119b964c270536c9dcc381ca824387 Mon Sep 17 00:00:00 2001 From: jake Date: Mon, 13 Nov 2023 23:55:26 -0700 Subject: [PATCH 57/58] this dep isn't even used --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 32363b6..dac1d62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,7 +65,6 @@ ages-prs = "0.1" async-trait = "0.1.51" async-recursion= "1.0.0" lazy_static = "1.4.0" -barrel = { version = "0.6.5", features = ["pg"] } refinery = { version = "0.5.0", features = ["postgres"] } sqlx = { version = "0.6.2", features = ["runtime-async-std-native-tls", "postgres", "json", "chrono"] } strum = "0.19.5" -- 2.36.0 From 250be01fab18199f63db8b3aa966f054545ce59d Mon Sep 17 00:00:00 2001 From: jake Date: Tue, 14 Nov 2023 00:06:05 -0700 Subject: [PATCH 58/58] another dead file --- src/items/src/manager.rs | 1380 -------------------------------------- 1 file changed, 1380 deletions(-) delete mode 100644 src/items/src/manager.rs diff --git a/src/items/src/manager.rs b/src/items/src/manager.rs deleted file mode 100644 index d368ec6..0000000 --- a/src/items/src/manager.rs +++ /dev/null @@ -1,1380 +0,0 @@ -use crate::ClientItemId; -use std::collections::HashMap; -use std::cmp::Ordering; -use std::cell::RefCell; -use thiserror::Error; -use crate::entity::gateway::{EntityGateway, GatewayError}; -use crate::entity::character::{CharacterEntity, CharacterEntityId, TechLevel}; -use crate::entity::item::{ItemDetail, ItemNote, BankName}; -use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, InventoryItemEntity, BankItemEntity}; -use crate::entity::item::tool::{Tool, ToolType}; -use crate::entity::item::weapon; -use maps::area::MapArea; -use crate::ship::ship::ItemDropLocation; -use crate::ship::trade::TradeItem; -use drops::{ItemDrop, ItemDropType}; -use location::{AreaClient, RoomId}; -use shops::ShopItem; -use crate::ship::packet::handler::trade::{TradeError, OTHER_MESETA_ITEM_ID}; - -use crate::bank::*; -use crate::floor::*; -use crate::inventory::*; -use crate::transaction::{ItemTransaction, ItemAction, TransactionError, TransactionCommitError}; - -#[derive(PartialEq, Eq)] -pub enum FloorType { - Local, - Shared, -} - -pub enum TriggerCreateItem { - Yes, - No -} - -#[derive(Error, Debug)] -#[error("itemmanager")] -pub enum ItemManagerError { - #[error("gateway")] - EntityGatewayError, - #[error("no such item id {0}")] - NoSuchItemId(ClientItemId), - NoCharacter(CharacterEntityId), - NoRoom(RoomId), - CouldNotAddToInventory(ClientItemId), - //ItemBelongsToOtherPlayer, - #[error("shrug")] - Idunnoman, - CouldNotSplitItem(ClientItemId), - #[error("could not drop meseta")] - CouldNotDropMeseta, - InvalidBankName(BankName), - #[error("not enough tools")] - NotEnoughTools(Tool, usize, usize), // have, expected - InventoryItemConsumeError(#[from] InventoryItemConsumeError), - #[error("bank full")] - BankFull, - WrongItemType(ClientItemId), - UseItemError(#[from] use_tool::UseItemError), - #[error("could not buy item")] - CouldNotBuyItem, - #[error("could not add bought item to inventory")] - CouldNotAddBoughtItemToInventory, - ItemIdNotInInventory(ClientItemId), - #[error("cannot get mut item")] - CannotGetMutItem, - #[error("cannot get individual item")] - CannotGetIndividualItem, - InvalidSlot(u8, u8), // slots available, slot attempted - #[error("no armor equipped")] - NoArmorEquipped, - GatewayError(#[from] GatewayError), - #[error("stacked item")] - StackedItemError(Vec), - #[error("item not sellable")] - ItemNotSellable(InventoryItem), - #[error("wallet full")] - WalletFull, - #[error("invalid sale")] - InvalidSale, - ItemTransactionAction(Box), - #[error("invalid trade")] - InvalidTrade, -} - -impl std::convert::From> for ItemManagerError -where - E: std::fmt::Debug + std::marker::Send + std::marker::Sync + std::error::Error + 'static, -{ - fn from(other: TransactionError) -> ItemManagerError { - match other { - TransactionError::Action(err) => { - ItemManagerError::ItemTransactionAction(Box::new(err)) - }, - TransactionError::Commit(err) => { - match err { - TransactionCommitError::Gateway(gw) => { - ItemManagerError::GatewayError(gw) - }, - TransactionCommitError::ItemManager(im) => { - im - } - } - } - } - } -} - - -pub struct ItemManager { - pub(super) id_counter: u32, - - pub(self) character_inventory: HashMap, - pub(self) character_meseta: HashMap, - pub(self) bank_meseta: HashMap, - //character_bank: HashMap>, - pub(self) character_bank: HashMap, - pub(self) character_floor: HashMap, - - pub(self) character_room: HashMap, - pub(self) room_floor: HashMap, - pub(self) room_item_id_counter: RefCell ClientItemId + Send>>>, -} - -impl Default for ItemManager { - fn default() -> ItemManager { - ItemManager { - id_counter: 0, - character_inventory: HashMap::new(), - character_meseta: HashMap::new(), - bank_meseta: HashMap::new(), - character_bank: HashMap::new(), - character_floor: HashMap::new(), - character_room: HashMap::new(), - room_floor: HashMap::new(), - room_item_id_counter: RefCell::new(HashMap::new()), - } - } -} - -impl ItemManager { - pub fn next_global_item_id(&mut self) -> ClientItemId { - self.id_counter += 1; - ClientItemId(self.id_counter) - } - - pub async fn load_character(&mut self, entity_gateway: &mut EG, character: &CharacterEntity) -> Result<(), anyhow::Error> { - let inventory = entity_gateway.get_character_inventory(&character.id).await?; - let bank = entity_gateway.get_character_bank(&character.id, &BankName("".into())).await?; - let equipped = entity_gateway.get_character_equips(&character.id).await?; - - let inventory_items = inventory.items.into_iter() - .map(|item| -> Result { - Ok(match item { - InventoryItemEntity::Individual(item) => { - InventoryItem::Individual(IndividualInventoryItem { - entity_id: item.id, - item_id: self.next_global_item_id(), - item: item.item, - }) - }, - InventoryItemEntity::Stacked(items) => { - InventoryItem::Stacked(StackedInventoryItem { - entity_ids: items.iter().map(|i| i.id).collect(), - item_id: self.next_global_item_id(), - tool: items.get(0) - .ok_or_else(|| ItemManagerError::StackedItemError(items.clone()))? - .item - .clone() - .as_tool() - .ok_or_else(|| ItemManagerError::StackedItemError(items.clone()))? - }) - }, - }) - }) - .collect::, _>>()?; - let character_inventory = CharacterInventory::new(inventory_items, &equipped); - - let bank_items = bank.items.into_iter() - .map(|item| -> Result { - Ok(match item { - BankItemEntity::Individual(item) => { - BankItem::Individual(IndividualBankItem { - entity_id: item.id, - item_id: self.next_global_item_id(), - item: item.item, - }) - }, - BankItemEntity::Stacked(items) => { - BankItem::Stacked(StackedBankItem { - entity_ids: items.iter().map(|i| i.id).collect(), - item_id: self.next_global_item_id(), - tool: items.get(0) - .ok_or_else(|| ItemManagerError::StackedItemError(items.clone()))? - .item - .clone() - .as_tool() - .ok_or_else(|| ItemManagerError::StackedItemError(items.clone()))? - }) - }, - }) - }) - .collect::, _>>()?; - let character_bank = CharacterBank::new(bank_items); - - let character_meseta = entity_gateway.get_character_meseta(&character.id).await?; - let bank_meseta = entity_gateway.get_bank_meseta(&character.id, &BankName("".into())).await?; - - self.character_inventory.insert(character.id, character_inventory); - self.character_bank.insert(character.id, character_bank); - self.character_meseta.insert(character.id, character_meseta); - self.bank_meseta.insert(character.id, bank_meseta); - Ok(()) - } - - pub fn add_character_to_room(&mut self, room_id: RoomId, character: &CharacterEntity, area_client: AreaClient) { - let base_inventory_id = ((area_client.local_client.id() as u32) << 21) | 0x10000; - let inventory = self.character_inventory.get_mut(&character.id).unwrap(); - inventory.initialize_item_ids(base_inventory_id); - let base_bank_id = ((area_client.local_client.id() as u32) << 21) | 0x20000; - let default_bank = self.character_bank.get_mut(&character.id); - if let Some(default_bank ) = default_bank { - default_bank.initialize_item_ids(base_bank_id); - } - self.character_room.insert(character.id, room_id); - self.character_floor.insert(character.id, RoomFloorItems::default()); - self.room_floor.entry(room_id).or_insert_with(RoomFloorItems::default); - - let mut inc = 0x00810000; - self.room_item_id_counter.borrow_mut().entry(room_id).or_insert_with(|| Box::new(move || { - inc += 1; - ClientItemId(inc) - })); - } - - pub fn get_character_inventory(&self, character: &CharacterEntity) -> Result<&CharacterInventory, anyhow::Error> { - Ok(self.character_inventory.get(&character.id) - .ok_or(ItemManagerError::NoCharacter(character.id))?) - } - - pub fn get_character_inventory_mut<'a>(&'a mut self, character: &CharacterEntity) -> Result<&'a mut CharacterInventory, anyhow::Error> { - Ok(self.character_inventory.get_mut(&character.id) - .ok_or(ItemManagerError::NoCharacter(character.id))?) - } - - pub fn get_character_bank(&self, character: &CharacterEntity) -> Result<&CharacterBank, anyhow::Error> { - self.character_bank - .get(&character.id) - .ok_or_else(|| ItemManagerError::NoCharacter(character.id).into()) - } - - pub fn get_character_meseta(&self, character_id: &CharacterEntityId) -> Result<&Meseta, ItemManagerError> { - self.character_meseta.get(character_id) - .ok_or(ItemManagerError::NoCharacter(*character_id)) - } - - pub fn get_character_meseta_mut<'a>(&'a mut self, character_id: &CharacterEntityId) -> Result<&'a mut Meseta, ItemManagerError> { - self.character_meseta.get_mut(character_id) - .ok_or(ItemManagerError::NoCharacter(*character_id)) - } - - pub fn get_bank_meseta(&self, character_id: &CharacterEntityId) -> Result<&Meseta, ItemManagerError> { - self.bank_meseta.get(character_id) - .ok_or(ItemManagerError::NoCharacter(*character_id)) - } - - pub fn get_bank_meseta_mut<'a>(&'a mut self, character_id: &CharacterEntityId) -> Result<&'a mut Meseta, ItemManagerError> { - self.bank_meseta.get_mut(character_id) - .ok_or(ItemManagerError::NoCharacter(*character_id)) - } - - pub fn get_character_and_bank_meseta_mut<'a>(&'a mut self, character_id: &CharacterEntityId) -> Result<(&'a mut Meseta, &'a mut Meseta), ItemManagerError> { - Ok(( - self.character_meseta.get_mut(character_id) - .ok_or(ItemManagerError::NoCharacter(*character_id))?, - self.bank_meseta.get_mut(character_id) - .ok_or(ItemManagerError::NoCharacter(*character_id))? - )) - } - - pub fn remove_character_from_room(&mut self, character: &CharacterEntity) { - self.character_inventory.remove(&character.id); - self.character_floor.remove(&character.id); - if let Some(room) = self.character_room.remove(&character.id).as_ref() { - if self.character_room.iter().any(|(_, r)| r == room) { - self.room_floor.remove(room); - } - } - } - - pub fn get_floor_item_by_id(&self, character: &CharacterEntity, item_id: ClientItemId) -> Result<(&FloorItem, FloorType), anyhow::Error> { - let local_floor = self.character_floor.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let room = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let shared_floor = self.room_floor.get(room).ok_or(ItemManagerError::NoCharacter(character.id))?; - - local_floor.get_item_by_id(item_id).map(|item| (item, FloorType::Local)) - .or_else(|| { - shared_floor.get_item_by_id(item_id).map(|item| (item, FloorType::Shared)) - }) - .ok_or_else(|| ItemManagerError::NoSuchItemId(item_id).into()) - } - - pub async fn character_picks_up_item(&mut self, entity_gateway: &mut EG, character: &mut CharacterEntity, item_id: ClientItemId) - -> Result { - let it = ItemTransaction::new(self, (character, item_id)) - .act(|it, (character, item_id)| -> Result<_, ItemManagerError> { - let local_floor = it.manager.character_floor.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let inventory = it.manager.character_inventory.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let room_id = it.manager.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let shared_floor = it.manager.room_floor.get(room_id).ok_or(ItemManagerError::NoRoom(*room_id))?; - - let floor_item = match local_floor.get_item_by_id(*item_id) { - Some(floor_item) => { - it.action(Box::new(RemoveFromLocalFloor { - character_id: character.id, - item_id: *item_id - })); - floor_item - }, - None => { - match shared_floor.get_item_by_id(*item_id) { - Some(floor_item) => { - it.action(Box::new(RemoveFromSharedFloor { - room_id: *room_id, - item_id: *item_id - })); - floor_item - }, - None => { - return Err(ItemManagerError::NoSuchItemId(*item_id)) - } - } - } - }; - - let create_trigger = match floor_item { - FloorItem::Individual(individual_floor_item) => { - if inventory.space_for_individual_item() { - it.action(Box::new(AddIndividualFloorItemToInventory { - character: (**character).clone(), - item: individual_floor_item.clone() - })) - } - else { - return Err(ItemManagerError::CouldNotAddToInventory(*item_id)); - } - TriggerCreateItem::Yes - }, - FloorItem::Stacked(stacked_floor_item) => { - match inventory.space_for_stacked_item(&stacked_floor_item.tool, stacked_floor_item.entity_ids.len()) { - SpaceForStack::Yes(YesThereIsSpace::NewStack) => { - it.action(Box::new(AddStackedFloorItemToInventory { - character_id: character.id, - item: stacked_floor_item.clone() - })); - TriggerCreateItem::Yes - }, - SpaceForStack::Yes(YesThereIsSpace::ExistingStack) => { - it.action(Box::new(AddStackedFloorItemToInventory { - character_id: character.id, - item: stacked_floor_item.clone() - })); - TriggerCreateItem::No - }, - SpaceForStack::No(_) => { - return Err(ItemManagerError::CouldNotAddToInventory(*item_id)); - }, - } - }, - FloorItem::Meseta(meseta_floor_item) => { - let character_meseta = it.manager.character_meseta.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - if character_meseta.0 >= 999999 { - return Err(ItemManagerError::CouldNotAddToInventory(*item_id)); - } - it.action(Box::new(AddMesetaFloorItemToInventory { - character_id: character.id, - item: meseta_floor_item.clone() - })); - - TriggerCreateItem::No - }, - }; - Ok(create_trigger) - }); - it.commit(self, entity_gateway) - .await - .map_err(|err| err.into()) - } - - pub async fn enemy_drop_item_on_local_floor<'a, EG: EntityGateway>(&'a mut self, entity_gateway: &'a mut EG, character: &'a CharacterEntity, item_drop: ItemDrop) -> Result<&'a FloorItem, anyhow::Error> { - let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - - enum ItemOrMeseta { - Individual(ItemDetail), - Stacked(Tool), - Meseta(Meseta) - } - - let item = match item_drop.item { - ItemDropType::Weapon(w) => ItemOrMeseta::Individual(ItemDetail::Weapon(w)), - ItemDropType::Armor(w) => ItemOrMeseta::Individual(ItemDetail::Armor(w)), - ItemDropType::Shield(w) => ItemOrMeseta::Individual(ItemDetail::Shield(w)), - ItemDropType::Unit(w) => ItemOrMeseta::Individual(ItemDetail::Unit(w)), - ItemDropType::TechniqueDisk(w) => ItemOrMeseta::Individual(ItemDetail::TechniqueDisk(w)), - ItemDropType::Mag(w) => ItemOrMeseta::Individual(ItemDetail::Mag(w)), - //ItemDropType::IndividualTool(t) => ItemOrMeseta::Individual(ItemDetail::Tool(t)), - //ItemDropType::StackedTool(t, _) => ItemOrMeseta::Stacked(t), - ItemDropType::Tool(t) if t.tool.is_stackable() => ItemOrMeseta::Stacked(t), - ItemDropType::Tool(t) if !t.tool.is_stackable() => ItemOrMeseta::Individual(ItemDetail::Tool(t)), - ItemDropType::Meseta(m) => ItemOrMeseta::Meseta(Meseta(m)), - _ => unreachable!() // rust isnt smart enough to see that the conditional on tool catches everything - }; - - let item_id = self.room_item_id_counter.borrow_mut().get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?(); - let floor_item = match item { - ItemOrMeseta::Individual(item_detail) => { - let entity = entity_gateway.create_item(NewItemEntity { - item: item_detail.clone(), - }).await?; - entity_gateway.add_item_note(&entity.id, ItemNote::EnemyDrop { - character_id: character.id, - map_area: item_drop.map_area, - x: item_drop.x, - y: item_drop.y, - z: item_drop.z, - }).await?; - FloorItem::Individual(IndividualFloorItem { - entity_id: entity.id, - item_id, - item: item_detail, - map_area: item_drop.map_area, - x: item_drop.x, - y: item_drop.y, - z: item_drop.z, - }) - }, - ItemOrMeseta::Stacked(tool) => { - let entity = entity_gateway.create_item(NewItemEntity { - item: ItemDetail::Tool(tool), - }).await?; - entity_gateway.add_item_note(&entity.id, ItemNote::EnemyDrop { - character_id: character.id, - map_area: item_drop.map_area, - x: item_drop.x, - y: item_drop.y, - z: item_drop.z, - }).await?; - FloorItem::Stacked(StackedFloorItem { - entity_ids: vec![entity.id], - item_id, - tool, - map_area: item_drop.map_area, - x: item_drop.x, - y: item_drop.y, - z: item_drop.z, - }) - }, - ItemOrMeseta::Meseta(meseta) => { - FloorItem::Meseta(MesetaFloorItem { - item_id, - meseta, - map_area: item_drop.map_area, - x: item_drop.x, - y: item_drop.y, - z: item_drop.z, - }) - }, - }; - - self.character_floor.entry(character.id).or_insert_with(RoomFloorItems::default).add_item(floor_item); - // TODO: make these real errors - self.character_floor.get(&character.id).ok_or(ItemManagerError::Idunnoman)?.get_item_by_id(item_id).ok_or_else(|| ItemManagerError::Idunnoman.into()) - } - - pub async fn player_drop_item_on_shared_floor(&mut self, - entity_gateway: &mut EG, - character: &CharacterEntity, - //inventory_item: InventoryItem, - item_id: ClientItemId, - item_drop_location: (MapArea, f32, f32, f32)) - -> Result<(), anyhow::Error> { - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let shared_floor = self.room_floor.get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?; - - let dropped_inventory_item = inventory.take_item_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; - - match dropped_inventory_item { - InventoryItem::Individual(individual_inventory_item) => { - let individual_floor_item = shared_floor.drop_individual_inventory_item(individual_inventory_item, item_drop_location); - entity_gateway.add_item_note( - &individual_floor_item.entity_id, - ItemNote::PlayerDrop { - character_id: character.id, - map_area: item_drop_location.0, - x: item_drop_location.1, - y: item_drop_location.2, - z: item_drop_location.3, - } - ).await?; - }, - InventoryItem::Stacked(stacked_inventory_item) => { - let stacked_floor_item = shared_floor.drop_stacked_inventory_item(stacked_inventory_item, item_drop_location); - for entity_id in &stacked_floor_item.entity_ids { - entity_gateway.add_item_note( - entity_id, - ItemNote::PlayerDrop { - character_id: character.id, - map_area: item_drop_location.0, - x: item_drop_location.1, - y: item_drop_location.2, - z: item_drop_location.3, - } - ).await?; - } - }, - } - - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - Ok(()) - } - - pub async fn player_drops_meseta_on_shared_floor(&mut self, - entity_gateway: &mut EG, - character: &mut CharacterEntity, - drop_location: ItemDropLocation, - amount: u32) - -> Result { - let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let shared_floor = self.room_floor.get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let character_meseta = self.character_meseta.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - if character_meseta.0 < amount { - return Err(ItemManagerError::CouldNotDropMeseta.into()) - } - character_meseta.0 -= amount; - entity_gateway.set_character_meseta(&character.id, *character_meseta).await?; - - let item_id = self.room_item_id_counter.borrow_mut().get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?(); - let floor_item = FloorItem::Meseta(MesetaFloorItem { - item_id, - meseta: Meseta(amount), - map_area: drop_location.map_area, - x: drop_location.x, - y: 0.0, - z: drop_location.z, - }); - - shared_floor.add_item(floor_item.clone()); - Ok(floor_item) - } - - pub async fn player_drops_partial_stack_on_shared_floor<'a, EG: EntityGateway>(&'a mut self, - entity_gateway: &'a mut EG, - character: &'a CharacterEntity, - //inventory_item: InventoryItem, - item_id: ClientItemId, - drop_location: ItemDropLocation, - amount: usize) - -> Result<&'a StackedFloorItem, anyhow::Error> { - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let shared_floor = self.room_floor.get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?; - - let item_to_split = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; - - let new_item_id = self.room_item_id_counter.borrow_mut().get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?(); - let stacked_floor_item = shared_floor.drop_partial_stacked_inventory_item(item_to_split, amount, new_item_id, (drop_location.map_area, drop_location.x, 0.0, drop_location.z)) - .ok_or(ItemManagerError::CouldNotSplitItem(item_id))?; - - for entity_id in &stacked_floor_item.entity_ids { - entity_gateway.add_item_note( - entity_id, - ItemNote::PlayerDrop { - character_id: character.id, - map_area: drop_location.map_area, - x: drop_location.x, - y: 0.0, - z: drop_location.z, - } - ).await?; - } - - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - Ok(stacked_floor_item) - } - - pub async fn player_consumes_tool(&mut self, - entity_gateway: &mut EG, - character: &mut CharacterEntity, - item_id: ClientItemId, - amount: usize) - -> Result { - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let used_item = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; - let consumed_item = used_item.consume(amount)?; - - if let ItemDetail::TechniqueDisk(tech_disk) = consumed_item.item() { - // TODO: validate tech level in packet is in bounds [1..30] - character.techs.set_tech(tech_disk.tech, TechLevel(tech_disk.level as u8)); - entity_gateway.save_character(character).await?; - }; - - for entity_id in consumed_item.entity_ids() { - entity_gateway.add_item_note(&entity_id, - ItemNote::Consumed).await?; - } - - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - Ok(consumed_item) - } - - pub async fn player_deposits_item(&mut self, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_id: ClientItemId, - amount: usize) - -> Result<(), anyhow::Error> { - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let bank = self.character_bank - .get_mut(&character.id) - .ok_or(ItemManagerError::NoCharacter(character.id))?; - - let item_to_deposit = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; - let _bank_item = bank.deposit_item(item_to_deposit, amount).ok_or(ItemManagerError::Idunnoman)?; - - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - entity_gateway.set_character_bank(&character.id, &bank.as_bank_entity(&character.id, &BankName("".into())), &BankName("".into())).await?; - Ok(()) - } - - pub async fn player_withdraws_item<'a, EG: EntityGateway>(&'a mut self, - entity_gateway: &'a mut EG, - character: &'a CharacterEntity, - item_id: ClientItemId, - amount: usize) - -> Result<&'a InventoryItem, anyhow::Error> { - - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let bank = self.character_bank - .get_mut(&character.id) - .ok_or(ItemManagerError::NoCharacter(character.id))?; - - let item_to_withdraw = bank.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; - let inventory_item_slot = { - let inventory_item = inventory.withdraw_item(item_to_withdraw, amount).ok_or(ItemManagerError::Idunnoman)?; - inventory_item.1 - }; - - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - entity_gateway.set_character_bank(&character.id, &bank.as_bank_entity(&character.id, &BankName("".into())), &BankName("".into())).await?; - inventory.slot(inventory_item_slot).ok_or_else(|| ItemManagerError::Idunnoman.into()) - } - - pub async fn player_feeds_mag_item(&mut self, - entity_gateway: &mut EG, - character: &CharacterEntity, - mag_id: ClientItemId, - tool_id: ClientItemId) - -> Result<(), anyhow::Error> { - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let consumed_tool = { - let item_to_feed = inventory.get_item_handle_by_id(tool_id).ok_or(ItemManagerError::NoSuchItemId(tool_id))?; - item_to_feed.consume(1)? - }; - let mut mag_handle = inventory.get_item_handle_by_id(mag_id).ok_or(ItemManagerError::NoSuchItemId(mag_id))?; - - let individual_item = mag_handle.item_mut() - .ok_or(ItemManagerError::NoSuchItemId(mag_id))? - .individual_mut() - .ok_or(ItemManagerError::WrongItemType(mag_id))?; - let mag = individual_item - .mag_mut() - .ok_or(ItemManagerError::WrongItemType(mag_id))?; - - let consumed_tool_type = match &consumed_tool { - ConsumedItem::Stacked(stacked_consumed_item) => stacked_consumed_item.tool.tool, - _ => return Err(ItemManagerError::WrongItemType(tool_id).into()) - }; - mag.feed(consumed_tool_type); - - for entity_id in consumed_tool.entity_ids() { - entity_gateway.feed_mag(&individual_item.entity_id, &entity_id).await?; - entity_gateway.add_item_note(&entity_id, ItemNote::FedToMag { - mag: individual_item.entity_id, - }).await?; - } - - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - Ok(()) - } - - pub async fn use_item(&mut self, - used_item: ConsumedItem, - entity_gateway: &mut EG, - character: &mut CharacterEntity) -> Result<(), anyhow::Error> { - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - match &used_item.item() { - ItemDetail::Weapon(_w) => { - // something like when items are used to combine/transform them? - //_ => {} - }, - ItemDetail::Tool(t) => { - match t.tool { - ToolType::PowerMaterial => { - use_tool::power_material(entity_gateway, character).await; - }, - ToolType::MindMaterial => { - use_tool::mind_material(entity_gateway, character).await; - }, - ToolType::EvadeMaterial => { - use_tool::evade_material(entity_gateway, character).await; - }, - ToolType::DefMaterial => { - use_tool::def_material(entity_gateway, character).await; - }, - ToolType::LuckMaterial => { - use_tool::luck_material(entity_gateway, character).await; - }, - ToolType::HpMaterial => { - use_tool::hp_material(entity_gateway, character).await; - }, - ToolType::TpMaterial => { - use_tool::tp_material(entity_gateway, character).await; - }, - ToolType::CellOfMag502 => { - use_tool::cell_of_mag_502(entity_gateway, &used_item, inventory).await?; - }, - ToolType::CellOfMag213 => { - use_tool::cell_of_mag_213(entity_gateway, &used_item, inventory).await?; - }, - ToolType::PartsOfRobochao => { - use_tool::parts_of_robochao(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeartOfOpaOpa => { - use_tool::heart_of_opaopa(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeartOfPian => { - use_tool::heart_of_pian(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeartOfChao=> { - use_tool::heart_of_chao(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeartOfAngel => { - use_tool::heart_of_angel(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfHamburger => { - use_tool::kit_of_hamburger(entity_gateway, &used_item, inventory).await?; - }, - ToolType::PanthersSpirit => { - use_tool::panthers_spirit(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfMark3 => { - use_tool::kit_of_mark3(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfMasterSystem=> { - use_tool::kit_of_master_system(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfGenesis => { - use_tool::kit_of_genesis(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfSegaSaturn => { - use_tool::kit_of_sega_saturn(entity_gateway, &used_item, inventory).await?; - }, - ToolType::KitOfDreamcast => { - use_tool::kit_of_dreamcast(entity_gateway, &used_item, inventory).await?; - }, - ToolType::Tablet => { - use_tool::tablet(entity_gateway, &used_item, inventory).await?; - }, - ToolType::DragonScale => { - use_tool::dragon_scale(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeavenStrikerCoat => { - use_tool::heaven_striker_coat(entity_gateway, &used_item, inventory).await?; - }, - ToolType::PioneerParts => { - use_tool::pioneer_parts(entity_gateway, &used_item, inventory).await?; - }, - ToolType::AmitiesMemo => { - use_tool::amities_memo(entity_gateway, &used_item, inventory).await?; - }, - ToolType::HeartOfMorolian => { - use_tool::heart_of_morolian(entity_gateway, &used_item, inventory).await?; - }, - ToolType::RappysBeak => { - use_tool::rappys_beak(entity_gateway, &used_item, inventory).await?; - }, - ToolType::YahoosEngine => { - use_tool::yahoos_engine(entity_gateway, &used_item, inventory).await?; - }, - ToolType::DPhotonCore => { - use_tool::d_photon_core(entity_gateway, &used_item, inventory).await?; - }, - ToolType::LibertaKit => { - use_tool::liberta_kit(entity_gateway, &used_item, inventory).await?; - }, - _ => {} - } - } - _ => {} - } - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - Ok(()) - } - - pub async fn player_buys_item<'a, EG: EntityGateway>(&'a mut self, - entity_gateway: &'a mut EG, - character: &'a CharacterEntity, - shop_item: &'a (dyn ShopItem + Send + Sync), - item_id: ClientItemId, - amount: usize) - -> Result<&'a InventoryItem, anyhow::Error> { - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - - let item_detail = shop_item.as_item(); - let inventory_item = match item_detail { - ItemDetail::Tool(tool) => { - if tool.is_stackable() { - let mut item_entities = Vec::new(); - for _ in 0..amount { - let item_entity = entity_gateway.create_item(NewItemEntity { - item: ItemDetail::Tool(tool), - }).await?; - entity_gateway.add_item_note(&item_entity.id, ItemNote::BoughtAtShop { - character_id: character.id, - }).await?; - item_entities.push(item_entity); - } - let floor_item = StackedFloorItem { - entity_ids: item_entities.into_iter().map(|i| i.id).collect(), - item_id, - tool, - // TODO: this is gonna choke if I ever require the item being near the player for pickup - map_area: MapArea::Pioneer2Ep1, - x: 0.0, - y: 0.0, - z: 0.0, - }; - let item_id = { - let (picked_up_item, _slot) = inventory.pick_up_stacked_floor_item(&floor_item).ok_or(ItemManagerError::CouldNotAddBoughtItemToInventory)?; - picked_up_item.item_id - }; - inventory.get_item_by_id(item_id).ok_or(ItemManagerError::ItemIdNotInInventory(item_id))? - } - else { - let item_entity = entity_gateway.create_item(NewItemEntity { - item: ItemDetail::Tool(tool), - }).await?; - entity_gateway.add_item_note(&item_entity.id, ItemNote::BoughtAtShop { - character_id: character.id, - }).await?; - - let floor_item = IndividualFloorItem { - entity_id: item_entity.id, - item_id, - item: ItemDetail::Tool(tool), - // TODO: this is gonna choke if I ever require the item being near the player for pickup - map_area: MapArea::Pioneer2Ep1, - x: 0.0, - y: 0.0, - z: 0.0, - }; - let item_id = { - let (picked_up_item, _slot) = inventory.pick_up_individual_floor_item(&floor_item).ok_or(ItemManagerError::CouldNotAddBoughtItemToInventory)?; - picked_up_item.item_id - }; - inventory.get_item_by_id(item_id).ok_or(ItemManagerError::ItemIdNotInInventory(item_id))? - } - }, - item_detail => { - let item_entity = entity_gateway.create_item(NewItemEntity { - item: item_detail.clone(), - }).await?; - entity_gateway.add_item_note(&item_entity.id, ItemNote::BoughtAtShop { - character_id: character.id, - }).await?; - let floor_item = IndividualFloorItem { - entity_id: item_entity.id, - item_id, - item: item_detail, - // TODO: this is gonna choke if I ever require the item being near the player for pickup - map_area: MapArea::Pioneer2Ep1, - x: 0.0, - y: 0.0, - z: 0.0, - }; - let item_id = { - let (picked_up_item, _slot) = inventory.pick_up_individual_floor_item(&floor_item).ok_or(ItemManagerError::CouldNotAddBoughtItemToInventory)?; - picked_up_item.item_id - }; - inventory.get_item_by_id(item_id).ok_or(ItemManagerError::ItemIdNotInInventory(item_id))? - }, - }; - - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - Ok(inventory_item) - } - - pub async fn player_sells_item(&mut self, - entity_gateway: &mut EG, - character: &mut CharacterEntity, - item_id: ClientItemId, - amount: usize) - -> Result<(), anyhow::Error> { - let character_meseta = self.get_character_meseta(&character.id)?.0; - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let sold_item_handle = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; - if let Some(item_sold) = sold_item_handle.item() { - let unit_price = item_sold.get_sell_price()?; { - let total_sale = unit_price * amount as u32; - if character_meseta + total_sale <= 999999 { - match item_sold { - InventoryItem::Individual(i) => { - entity_gateway.add_item_note(&i.entity_id, ItemNote::SoldToShop).await?; - inventory.remove_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; - }, - InventoryItem::Stacked(s) => { - match amount.cmp(&s.count()) { - Ordering::Less | Ordering::Equal => { - sold_item_handle.consume(amount)?; - }, - Ordering::Greater => return Err(ItemManagerError::InvalidSale.into()), - }; - }, - } - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - let character_meseta = self.get_character_meseta_mut(&character.id)?; - character_meseta.0 += total_sale; - entity_gateway.set_character_meseta(&character.id, *character_meseta).await?; - } - else { - return Err(ItemManagerError::WalletFull.into()) - } - } - } else { - return Err(ItemManagerError::ItemIdNotInInventory(item_id).into()) - } - Ok(()) - } - - // TODO: check if slot exists before putting units into it - pub async fn player_equips_item(&mut self, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_id: ClientItemId, - equip_slot: u8) - -> Result<(), anyhow::Error> { - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - inventory.equip(&item_id, equip_slot); - entity_gateway.set_character_equips(&character.id, &inventory.as_equipped_entity()).await?; - Ok(()) - } - - pub async fn player_unequips_item(&mut self, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_id: ClientItemId) - -> Result<(), anyhow::Error> { - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - inventory.unequip(&item_id); - entity_gateway.set_character_equips(&character.id, &inventory.as_equipped_entity()).await?; - Ok(()) - } - - pub async fn player_sorts_items(&mut self, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_ids: [u32; 30]) - -> Result<(), anyhow::Error> { - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let sorted_inventory_items: Vec = item_ids.iter() - .filter(|&client_item_id| *client_item_id < 0xFFFFFFFF) - .map(|&client_item_id| inventory.get_item_by_id(ClientItemId(client_item_id))) - .filter(|&x| x.is_some()) - .map(|x| x.cloned().unwrap()) - .collect(); - - inventory.set_items(sorted_inventory_items); - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - Ok(()) - } - - pub async fn replace_item_with_tekked(&mut self, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_id: ClientItemId, - tek: weapon::WeaponModifier) - -> Result { - let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - - let item = inventory.remove_by_id(item_id) - .ok_or(ItemManagerError::NoSuchItemId(item_id))?; - let individual = item - .individual() - .ok_or(ItemManagerError::WrongItemType(item_id))?; - - let entity_id = individual.entity_id; - let mut weapon = *individual - .weapon() - .ok_or(ItemManagerError::WrongItemType(item_id))?; - - weapon.apply_modifier(&tek); - entity_gateway.add_weapon_modifier(&entity_id, tek).await?; - - inventory.add_item(InventoryItem::Individual(IndividualInventoryItem { - entity_id, - item_id, - item: ItemDetail::Weapon(weapon), - })); - - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - - Ok(weapon) - } - - pub async fn trade_items(&mut self, - entity_gateway: &mut EG, - room_id: RoomId, - p1: (&AreaClient, &CharacterEntity, &Vec, usize), - p2: (&AreaClient, &CharacterEntity, &Vec, usize)) - -> Result, anyhow::Error> { - let it = ItemTransaction::new(self, (p1, p2, room_id)) - .act(|it, (p1, p2, room_id)| -> Result<_, anyhow::Error> { - let p1_inventory = it.manager.get_character_inventory(p1.1)?; - let p2_inventory = it.manager.get_character_inventory(p2.1)?; - - [(p2_inventory, p1_inventory, p2.2, p1.2), (p1_inventory, p2_inventory, p1.2, p2.2)].iter() - .map(|(src_inventory, dest_inventory, trade_recv, trade_send)| { - let item_slots_lost_to_trade = trade_send - .iter() - .fold(0, |acc, item| { - match item { - TradeItem::Individual(..) => { - acc + 1 - }, - TradeItem::Stacked(item_id, amount) => { - let stacked_inventory_item = try { - src_inventory - .get_item_by_id(*item_id)? - .stacked() - }; - if let Some(Some(item)) = stacked_inventory_item { - if item.count() == *amount { - acc + 1 - } - else { - acc - } - } - else { - acc - } - } - } - }); - trade_recv - .iter() - .try_fold(dest_inventory.count(), |acc, item| { - match item { - TradeItem::Individual(..) => { - if acc >= (30 + item_slots_lost_to_trade) { - Err(TradeError::NoInventorySpace) - } - else { - Ok(acc + 1) - } - }, - TradeItem::Stacked(item_id, amount) => { - let stacked_inventory_item = src_inventory - .get_item_by_id(*item_id) - .ok_or(TradeError::InvalidItemId(*item_id))? - .stacked() - .ok_or(TradeError::InvalidItemId(*item_id))?; - match dest_inventory.space_for_stacked_item(&stacked_inventory_item.tool, *amount) { - SpaceForStack::Yes(YesThereIsSpace::ExistingStack) => { - Ok(acc) - }, - SpaceForStack::Yes(YesThereIsSpace::NewStack) => { - Ok(acc + 1) - }, - SpaceForStack::No(NoThereIsNotSpace::FullStack) => { - Err(TradeError::NoStackSpace) - }, - SpaceForStack::No(NoThereIsNotSpace::FullInventory) => { - if acc >= (30 + item_slots_lost_to_trade) { - Err(TradeError::NoInventorySpace) - } - else { - Ok(acc + 1) - } - }, - } - } - } - }) - }) - .collect::, _>>()?; - - let trade_items = [(p1, p2, p1_inventory), (p2, p1, p2_inventory)] - .map(|(src_client, dest_client, src_inventory)| { - src_client.2.iter() - .map(|item| -> Option<(Option, Box>)> { - match item { - TradeItem::Individual(item_id) => { - let item = src_inventory.get_item_by_id(*item_id)?.individual()?; - let new_item_id = it.manager.room_item_id_counter.borrow_mut().get_mut(room_id)?(); - Some(( - Some(ItemToTrade { - add_to: *dest_client.0, - remove_from: *src_client.0, - current_item_id: *item_id, - new_item_id, - item_detail: ItemToTradeDetail::Individual(item.item.clone()) - }), - Box::new(TradeIndividualItem { - src_character_id: src_client.1.id, - dest_character_id: dest_client.1.id, - current_item_id: *item_id, - new_item_id, - }), - )) - }, - TradeItem::Stacked(item_id, amount) => { - let item = src_inventory.get_item_by_id(*item_id)?.stacked()?; - if item.count() < *amount { - None - } - else { - let new_item_id = it.manager.room_item_id_counter.borrow_mut().get_mut(room_id)?(); - Some(( - Some(ItemToTrade { - add_to: *dest_client.0, - remove_from: *src_client.0, - current_item_id: *item_id, - new_item_id, - item_detail: ItemToTradeDetail::Stacked(item.tool, *amount) - }), - Box::new(TradeStackedItem { - src_character_id: src_client.1.id, - dest_character_id: dest_client.1.id, - //item_ids: item.entity_ids.iter().cloned().take(*amount).collect(), - current_item_id: *item_id, - new_item_id, - amount: *amount, - }), - )) - } - } - } - }) - .chain( - if src_client.3 > 0 { - Box::new(std::iter::once(Some( - (Some(ItemToTrade { - add_to: *dest_client.0, - remove_from: *src_client.0, - current_item_id: OTHER_MESETA_ITEM_ID, - new_item_id: OTHER_MESETA_ITEM_ID, - item_detail: ItemToTradeDetail::Meseta(src_client.3) - }), - Box::new(TradeMeseta { - src_character_id: src_client.1.id, - dest_character_id: dest_client.1.id, - amount: src_client.3, - }) as Box>)))) as Box> - } - else { - Box::new(std::iter::empty()) as Box> - }) - .collect::>>() - }); - - - if let [Some(p1_trades), Some(p2_trades)] = trade_items { - let (p1_item_trades, p1_item_actions): (Vec<_>, Vec<_>) = p1_trades.into_iter().unzip(); - let (p2_item_trades, p2_item_actions): (Vec<_>, Vec<_>) = p2_trades.into_iter().unzip(); - - let item_trades = p1_item_trades.into_iter().flatten().chain(p2_item_trades.into_iter().flatten()); - let item_actions = p1_item_actions.into_iter().chain(p2_item_actions.into_iter()); - - for action in item_actions { - it.action(action); - } - - Ok(item_trades.collect()) - } - else { - Err(ItemManagerError::InvalidTrade.into()) - } - - }); - it.commit(self, entity_gateway) - .await - .map_err(|err| err.into()) - } -} - -#[derive(Debug)] -pub enum ItemToTradeDetail { - Individual(ItemDetail), - Stacked(Tool, usize), - Meseta(usize), -} - -#[derive(Debug)] -pub struct ItemToTrade { - pub add_to: AreaClient, - pub remove_from: AreaClient, - pub current_item_id: ClientItemId, - pub new_item_id: ClientItemId, - pub item_detail: ItemToTradeDetail, -} - - -#[derive(Debug)] -struct RemoveFromLocalFloor { - character_id: CharacterEntityId, - item_id: ClientItemId, -} - -#[async_trait::async_trait] -impl ItemAction for RemoveFromLocalFloor { - async fn commit(&self, item_manager: &mut ItemManager, _entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - let local_floor = item_manager.character_floor.get_mut(&self.character_id).ok_or(ItemManagerError::NoCharacter(self.character_id))?; - local_floor.remove_item(&self.item_id); - Ok(()) - } -} - - -#[derive(Debug)] -struct RemoveFromSharedFloor { - room_id: RoomId, - item_id: ClientItemId, -} - -#[async_trait::async_trait] -impl ItemAction for RemoveFromSharedFloor { - async fn commit(&self, item_manager: &mut ItemManager, _entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - let shared_floor = item_manager.room_floor.get_mut(&self.room_id).ok_or(ItemManagerError::NoRoom(self.room_id))?; - shared_floor.remove_item(&self.item_id); - Ok(()) - } -} - - -#[derive(Debug)] -struct AddIndividualFloorItemToInventory{ - character: CharacterEntity, - item: IndividualFloorItem, -} - -#[async_trait::async_trait] -impl ItemAction for AddIndividualFloorItemToInventory { - async fn commit(&self, item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - let inventory = item_manager.character_inventory.get_mut(&self.character.id).ok_or(ItemManagerError::NoCharacter(self.character.id))?; - let inv_item = inventory.add_individual_floor_item(&self.item); - - entity_gateway.add_item_note( - &self.item.entity_id, - ItemNote::Pickup { - character_id: self.character.id, - } - ).await?; - - if inv_item.mag().is_some() { - entity_gateway.change_mag_owner(&self.item.entity_id, &self.character).await?; - } - - entity_gateway.set_character_inventory(&self.character.id, &inventory.as_inventory_entity(&self.character.id)).await?; - Ok(()) - } -} - - -#[derive(Debug)] -struct AddStackedFloorItemToInventory{ - character_id: CharacterEntityId, - item: StackedFloorItem, -} - -#[async_trait::async_trait] -impl ItemAction for AddStackedFloorItemToInventory { - async fn commit(&self, item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - let inventory = item_manager.character_inventory.get_mut(&self.character_id).ok_or(ItemManagerError::NoCharacter(self.character_id))?; - inventory.add_stacked_floor_item(&self.item); - - entity_gateway.set_character_inventory(&self.character_id, &inventory.as_inventory_entity(&self.character_id)).await?; - Ok(()) - } -} - - -#[derive(Debug)] -struct AddMesetaFloorItemToInventory{ - character_id: CharacterEntityId, - item: MesetaFloorItem, -} - -#[async_trait::async_trait] -impl ItemAction for AddMesetaFloorItemToInventory { - async fn commit(&self, item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - let character_meseta = item_manager.character_meseta.get_mut(&self.character_id).ok_or(ItemManagerError::NoCharacter(self.character_id))?; - character_meseta.0 = std::cmp::min(character_meseta.0 + self.item.meseta.0, 999999); - entity_gateway.set_character_meseta(&self.character_id, *character_meseta).await?; - Ok(()) - } -} - - -#[derive(Debug)] -struct TradeIndividualItem { - src_character_id: CharacterEntityId, - dest_character_id: CharacterEntityId, - current_item_id: ClientItemId, - new_item_id: ClientItemId, -} - -#[async_trait::async_trait] -impl ItemAction for TradeIndividualItem { - async fn commit(&self, item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - let src_inventory = item_manager.character_inventory.get_mut(&self.src_character_id).ok_or(ItemManagerError::NoCharacter(self.src_character_id))?; - let inventory_item = src_inventory.take_item_by_id(self.current_item_id).ok_or(ItemManagerError::NoSuchItemId(self.current_item_id))?; - entity_gateway.set_character_inventory(&self.src_character_id, &src_inventory.as_inventory_entity(&self.src_character_id)).await?; - - let dest_inventory = item_manager.character_inventory.get_mut(&self.dest_character_id).ok_or(ItemManagerError::NoCharacter(self.dest_character_id))?; - dest_inventory.add_item_with_new_item_id(inventory_item, self.new_item_id); - entity_gateway.set_character_inventory(&self.dest_character_id, &dest_inventory.as_inventory_entity(&self.dest_character_id)).await?; - - Ok(()) - } -} - -#[derive(Debug)] -struct TradeStackedItem { - src_character_id: CharacterEntityId, - dest_character_id: CharacterEntityId, - current_item_id: ClientItemId, - new_item_id: ClientItemId, - amount: usize, -} - -#[async_trait::async_trait] -impl ItemAction for TradeStackedItem { - async fn commit(&self, item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - let src_inventory = item_manager.character_inventory.get_mut(&self.src_character_id).ok_or(ItemManagerError::NoCharacter(self.src_character_id))?; - let inventory_item = src_inventory.take_stacked_item_by_id(self.current_item_id, self.amount).ok_or(ItemManagerError::NoSuchItemId(self.current_item_id))?; - entity_gateway.set_character_inventory(&self.src_character_id, &src_inventory.as_inventory_entity(&self.src_character_id)).await?; - - let dest_inventory = item_manager.character_inventory.get_mut(&self.dest_character_id).ok_or(ItemManagerError::NoCharacter(self.dest_character_id))?; - dest_inventory.add_item_with_new_item_id(InventoryItem::Stacked(inventory_item), self.new_item_id); - entity_gateway.set_character_inventory(&self.dest_character_id, &dest_inventory.as_inventory_entity(&self.dest_character_id)).await?; - - Ok(()) - } -} - -#[derive(Debug)] -struct TradeMeseta { - src_character_id: CharacterEntityId, - dest_character_id: CharacterEntityId, - amount: usize, -} - -#[async_trait::async_trait] -impl ItemAction for TradeMeseta { - async fn commit(&self, item_manager: &mut ItemManager, entity_gateway: &mut EG) -> Result<(), TransactionCommitError> { - { - let src_meseta = item_manager.get_character_meseta_mut(&self.src_character_id)?; - src_meseta.0 -= self.amount as u32; - entity_gateway.set_character_meseta(&self.src_character_id, *src_meseta).await?; - } - { - let dest_meseta = item_manager.get_character_meseta_mut(&self.dest_character_id)?; - dest_meseta.0 += self.amount as u32; - entity_gateway.set_character_meseta(&self.dest_character_id, *dest_meseta).await?; - } - Ok(()) - } -} -- 2.36.0