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 ec3f132..33e8aa6 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)] @@ -391,8 +326,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, } @@ -445,13 +380,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 } @@ -479,7 +414,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))), @@ -520,7 +455,7 @@ pub struct ShipServerState { pub(crate) item_state: items::state::ItemState, shops: ItemShops, pub blocks: Blocks, - event: ShipEvent, + event: Holiday, ip: Ipv4Addr, port: u16, @@ -529,7 +464,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 {