#![allow(dead_code)] use networking::serverstate::{ClientId, ServerState}; use entity::gateway::EntityGateway; use entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity}; use entity::character::{CharacterEntity, NewCharacterEntity, SectionID}; use entity::item::{Meseta, BankIdentifier}; use ship_server::{ShipServerState, ShipServerStateBuilder, RecvShipPacket}; use maps::room::{RoomMode, Difficulty, Episode}; use maps::area::MapArea; use maps::maps::null_free_roam_maps; use maps::object::MapObject; use maps::monster::MonsterType; use quests::{QuestList, QuestLoadError}; use drops::{DropTable, ItemDropType}; use shops::{ItemShops, WeaponShopItem, ToolShopItem, ArmorShopItem}; use entity::item; use libpso::packet::ship::*; use libpso::packet::login::{Login, Session}; use libpso::util::{utf8_to_array, utf8_to_utf16_array}; fn null_quest_builder(_mode: RoomMode) -> Result { Ok(Default::default()) } struct NullDropTable; impl DropTable for NullDropTable { fn get_drop(&mut self, _map_area: &MapArea, _monster: &MonsterType) -> Option { None } fn get_box_drop(&mut self, _map_area: &MapArea, _object: &MapObject) -> Option { None } } pub fn null_drop_table_builder(_episode: Episode, _difficult: Difficulty, _section_id: SectionID) -> Box { Box::new(NullDropTable) } struct NullItemShops; #[async_trait::async_trait] impl ItemShops for NullItemShops { async fn generate_weapon_list(&self, _difficulty: Difficulty, _section_id: SectionID, _char_level: usize) -> Option> { Some(Vec::new()) } async fn generate_tool_list(&self, _char_level: usize) -> Vec { Vec::new() } async fn generate_armor_list(&self, _char_level: usize) -> Vec { Vec::new() } } pub fn standard_ship_buildable(gateway: EG) -> ShipServerStateBuilder { ShipServerState::builder() .gateway(gateway) .standard_quest_builder(Box::new(null_quest_builder)) .government_quest_builder(Box::new(null_quest_builder)) .drop_table_builder(Box::new(null_drop_table_builder)) .map_builder(Box::new(null_free_roam_maps)) .item_shops(NullItemShops) } pub fn standard_ship(gateway: EG) -> ShipServerState { ShipServerState::builder() .gateway(gateway) .standard_quest_builder(Box::new(null_quest_builder)) .government_quest_builder(Box::new(null_quest_builder)) .drop_table_builder(Box::new(null_drop_table_builder)) .map_builder(Box::new(null_free_roam_maps)) .item_shops(NullItemShops) .build() } //TODO: remove kb_conf_preset pub async fn new_user_character(entity_gateway: &mut EG, username: &str, password: &str) -> (UserAccountEntity, CharacterEntity) { let new_user = NewUserAccountEntity { email: format!("{}@pso.com", username), username: username.into(), password: bcrypt::hash(password, 5).unwrap(), guildcard: 1, activated: true, ..NewUserAccountEntity::default() }; let user = entity_gateway.create_user(new_user).await.unwrap(); let new_settings = NewUserSettingsEntity::new(user.id); let _settings = entity_gateway.create_user_settings(new_settings).await.unwrap(); let new_character = NewCharacterEntity::new(user.id); let character = entity_gateway.create_character(new_character).await.unwrap(); entity_gateway.set_character_meseta(&character.id, Meseta(0)).await.unwrap(); entity_gateway.set_bank_meseta(&character.id, &BankIdentifier::Character, Meseta(0)).await.unwrap(); (user, character) } pub async fn log_in_char(ship: &mut ShipServerState, id: ClientId, username: &str, password: &str) { let username = username.to_string(); let password = password.to_string(); ship.handle(id, RecvShipPacket::Login(Login { tag: 0, guildcard: 0, version: 0, unknown1: [0; 6], team: 0, username: utf8_to_array(&username), unknown2: [0; 32], password: utf8_to_array(&password), unknown3: [0; 40], hwinfo: [0; 8], session: Session::default(), })).await.unwrap(); } pub async fn join_lobby(ship: &mut ShipServerState, id: ClientId) { ship.handle(id, RecvShipPacket::CharData(CharData { _unknown: [0; 0x828] })).await.unwrap(); } pub async fn create_room(ship: &mut ShipServerState, id: ClientId, name: &str, password: &str) { create_room_with_difficulty(ship, id, name, password, Difficulty::Normal).await; } pub async fn leave_room(ship: &mut ShipServerState, id: ClientId) { ship.handle(id, RecvShipPacket::LobbySelect(LobbySelect { menu: 3, lobby: 0, })).await.unwrap(); } pub async fn create_room_with_difficulty(ship: &mut ShipServerState, id: ClientId, name: &str, password: &str, difficulty: Difficulty) { ship.handle(id, RecvShipPacket::CreateRoom(CreateRoom { unknown: [0; 2], name: utf8_to_utf16_array(name), password: utf8_to_utf16_array(password), difficulty: difficulty.into(), battle: 0, challenge: 0, episode: 1, single_player: 0, padding: [0; 3], })).await.unwrap(); ship.handle(id, RecvShipPacket::DoneBursting(DoneBursting {})).await.unwrap(); } pub async fn join_room(ship: &mut ShipServerState, id: ClientId, room_id: u32) { ship.handle(id, RecvShipPacket::MenuSelect(MenuSelect { menu: ROOM_MENU_ID, item: room_id, })).await.unwrap(); ship.handle(id, RecvShipPacket::DoneBursting(DoneBursting {})).await.unwrap(); } pub struct WeaponBuilder { weapon: item::weapon::WeaponType, grind: u8, special: Option, attributes: [Option; 3], tekked: bool, } impl WeaponBuilder { fn new(weapon: item::weapon::WeaponType) -> WeaponBuilder { WeaponBuilder { weapon, grind: 0, special: None, attributes: [None; 3], tekked: true, } } pub fn grind(self, grind: u8) -> WeaponBuilder { WeaponBuilder { grind, ..self } } pub fn special(self, special: item::weapon::WeaponSpecial) -> WeaponBuilder { WeaponBuilder { special: Some(special), ..self } } pub fn attr(mut self, attr: item::weapon::Attribute, value: i8) -> WeaponBuilder { self.attributes .iter_mut() .find(|k| k.is_none()) .map(|empty_attr| { *empty_attr = Some(item::weapon::WeaponAttribute { attr, value, }) }); self } pub fn untekked(self) -> WeaponBuilder { WeaponBuilder { tekked: false, ..self } } pub fn as_new(self) -> item::NewItemEntity { item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { weapon: self.weapon, grind: self.grind, special: self.special, attrs: self.attributes, tekked: self.tekked, } ) } } } pub struct ArmorBuilder { armor: item::armor::ArmorType, dfp: u8, evp: u8, slots: u8, } impl ArmorBuilder { pub fn new(armor: item::armor::ArmorType) -> ArmorBuilder { ArmorBuilder { armor: armor, dfp: 0, evp: 0, slots: 0, } } pub fn slots(self, slots: u8) -> ArmorBuilder { ArmorBuilder { slots, ..self } } pub fn dfp(self, dfp: u8) -> ArmorBuilder { ArmorBuilder { dfp, ..self } } pub fn evp(self, evp: u8) -> ArmorBuilder { ArmorBuilder { evp, ..self } } pub fn as_new(self) -> item::NewItemEntity { item::NewItemEntity { item: item::ItemDetail::Armor( item::armor::Armor { armor: self.armor, dfp: self.dfp, evp: self.evp, slots: self.slots, } ) } } } pub struct ShieldBuilder { shield: item::shield::ShieldType, dfp: u8, evp: u8, } impl ShieldBuilder { pub fn new(shield: item::shield::ShieldType) -> ShieldBuilder { ShieldBuilder { shield: shield, dfp: 0, evp: 0, } } pub fn dfp(self, dfp: u8) -> ShieldBuilder { ShieldBuilder { dfp, ..self } } pub fn evp(self, evp: u8) -> ShieldBuilder { ShieldBuilder { evp, ..self } } pub fn as_new(self) -> item::NewItemEntity { item::NewItemEntity { item: item::ItemDetail::Shield( item::shield::Shield { shield: self.shield, dfp: self.dfp, evp: self.evp, } ) } } } pub struct UnitBuilder { unit: item::unit::UnitType, modifier: Option, } impl UnitBuilder { pub fn modifier(self, modifier: item::unit::UnitModifier) -> UnitBuilder { UnitBuilder { modifier: Some(modifier), ..self } } pub fn as_new(self) -> item::NewItemEntity { item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit { unit: self.unit, modifier: self.modifier, } ) } } } pub struct MagBuilder { } impl MagBuilder { pub fn as_new(self) -> item::NewItemEntity { item::NewItemEntity { item: item::ItemDetail::Mag( item::mag::Mag::baby_mag(0) ) } } } pub struct ToolBuilder { tool: item::tool::ToolType, } impl ToolBuilder { pub fn as_new(self) -> item::NewItemEntity { item::NewItemEntity { item: item::ItemDetail::Tool ( item::tool::Tool { tool: self.tool, } ), } } } pub struct TechBuilder { tech: item::tech::Technique, level: u32, } impl TechBuilder { pub fn level(self, level: u32) -> TechBuilder { TechBuilder { level, ..self } } pub fn as_new(self) -> item::NewItemEntity { item::NewItemEntity { item: item::ItemDetail::TechniqueDisk ( item::tech::TechniqueDisk { tech: self.tech, level: self.level, } ) } } } pub struct ItemBuilder; impl ItemBuilder { pub fn weapon(weapon: item::weapon::WeaponType) -> WeaponBuilder { WeaponBuilder::new(weapon) } pub fn armor(armor: item::armor::ArmorType) -> ArmorBuilder { ArmorBuilder::new(armor) } pub fn shield(shield: item::shield::ShieldType) -> ShieldBuilder { ShieldBuilder::new(shield) } pub fn unit(unit: item::unit::UnitType) -> UnitBuilder { UnitBuilder { unit: unit, modifier: None, } } pub fn baby_mag() -> MagBuilder { MagBuilder { } } pub fn tool(tool: item::tool::ToolType) -> ToolBuilder { ToolBuilder { tool: tool, } } pub fn tech(tech: item::tech::Technique) -> TechBuilder { TechBuilder { tech: tech, level: 0, } } }