You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
6.7 KiB

4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
  1. #![allow(dead_code)]
  2. use networking::serverstate::{ClientId, ServerState};
  3. use entity::gateway::EntityGateway;
  4. use entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity};
  5. use entity::character::{CharacterEntity, NewCharacterEntity, SectionID};
  6. use entity::item::{Meseta, BankIdentifier};
  7. use elseware::ship::ship::{ShipServerState, ShipServerStateBuilder, RecvShipPacket};
  8. use maps::room::{RoomMode, Difficulty, Episode};
  9. use maps::area::MapArea;
  10. use maps::maps::null_free_roam_maps;
  11. use maps::object::MapObject;
  12. use maps::monster::MonsterType;
  13. use quests::{QuestList, QuestLoadError};
  14. use drops::{DropTable, ItemDropType};
  15. use shops::{ItemShops, WeaponShopItem, ToolShopItem, ArmorShopItem};
  16. use entity::item;
  17. use libpso::packet::ship::*;
  18. use libpso::packet::login::{Login, Session};
  19. use libpso::{utf8_to_array, utf8_to_utf16_array};
  20. fn null_quest_builder(_mode: RoomMode) -> Result<QuestList, QuestLoadError> {
  21. Ok(Default::default())
  22. }
  23. struct NullDropTable;
  24. impl DropTable for NullDropTable {
  25. fn get_drop(&mut self, _map_area: &MapArea, _monster: &MonsterType) -> Option<ItemDropType> {
  26. None
  27. }
  28. fn get_box_drop(&mut self, _map_area: &MapArea, _object: &MapObject) -> Option<ItemDropType> {
  29. None
  30. }
  31. }
  32. struct NullItemShops;
  33. #[async_trait::async_trait]
  34. impl ItemShops for NullItemShops {
  35. async fn generate_weapon_list(&self, _difficulty: Difficulty, _section_id: SectionID, _char_level: usize) -> Option<Vec<WeaponShopItem>> {
  36. Some(Vec::new())
  37. }
  38. async fn generate_tool_list(&self, _char_level: usize) -> Vec<ToolShopItem> {
  39. Vec::new()
  40. }
  41. async fn generate_armor_list(&self, _char_level: usize) -> Vec<ArmorShopItem> {
  42. Vec::new()
  43. }
  44. }
  45. pub fn null_drop_table_builder(_episode: Episode, _difficult: Difficulty, _section_id: SectionID) -> Box<dyn DropTable + Send + Sync> {
  46. Box::new(NullDropTable)
  47. }
  48. pub fn standard_ship_buildable<EG: EntityGateway + Clone>(gateway: EG) -> ShipServerStateBuilder<EG> {
  49. ShipServerState::builder()
  50. .gateway(gateway)
  51. .standard_quest_builder(Box::new(null_quest_builder))
  52. .government_quest_builder(Box::new(null_quest_builder))
  53. .drop_table_builder(Box::new(null_drop_table_builder))
  54. .map_builder(Box::new(null_free_roam_maps))
  55. .item_shops(NullItemShops)
  56. }
  57. pub fn standard_ship<EG: EntityGateway + Clone>(gateway: EG) -> ShipServerState<EG> {
  58. ShipServerState::builder()
  59. .gateway(gateway)
  60. .standard_quest_builder(Box::new(null_quest_builder))
  61. .government_quest_builder(Box::new(null_quest_builder))
  62. .drop_table_builder(Box::new(null_drop_table_builder))
  63. .map_builder(Box::new(null_free_roam_maps))
  64. .item_shops(NullItemShops)
  65. .build()
  66. }
  67. //TODO: remove kb_conf_preset
  68. pub async fn new_user_character<EG: EntityGateway + Clone>(entity_gateway: &mut EG, username: &str, password: &str, kb_conf_preset: usize) -> (UserAccountEntity, CharacterEntity) {
  69. let new_user = NewUserAccountEntity {
  70. email: format!("{}@pso.com", username),
  71. username: username.into(),
  72. password: bcrypt::hash(password, 5).unwrap(),
  73. guildcard: 1,
  74. activated: true,
  75. ..NewUserAccountEntity::default()
  76. };
  77. let user = entity_gateway.create_user(new_user).await.unwrap();
  78. let new_settings = NewUserSettingsEntity::new(user.id);
  79. let _settings = entity_gateway.create_user_settings(new_settings).await.unwrap();
  80. let new_character = NewCharacterEntity::new(user.id);
  81. let character = entity_gateway.create_character(new_character).await.unwrap();
  82. entity_gateway.set_character_meseta(&character.id, Meseta(0)).await.unwrap();
  83. entity_gateway.set_bank_meseta(&character.id, &BankIdentifier::Character, Meseta(0)).await.unwrap();
  84. (user, character)
  85. }
  86. pub async fn log_in_char<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId, username: &str, password: &str) {
  87. let username = username.to_string();
  88. let password = password.to_string();
  89. ship.handle(id, RecvShipPacket::Login(Login {
  90. tag: 0,
  91. guildcard: 0,
  92. version: 0,
  93. unknown1: [0; 6],
  94. team: 0,
  95. username: utf8_to_array!(username, 16),
  96. unknown2: [0; 32],
  97. password: utf8_to_array!(password, 16),
  98. unknown3: [0; 40],
  99. hwinfo: [0; 8],
  100. session: Session::new(),
  101. })).await.unwrap();
  102. }
  103. pub async fn join_lobby<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId) {
  104. ship.handle(id, RecvShipPacket::CharData(CharData {
  105. _unknown: [0; 0x828]
  106. })).await.unwrap();
  107. }
  108. pub async fn create_room<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId, name: &str, password: &str) {
  109. create_room_with_difficulty(ship, id, name, password, Difficulty::Normal).await;
  110. }
  111. pub async fn leave_room<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId) {
  112. ship.handle(id, RecvShipPacket::LobbySelect(LobbySelect {
  113. menu: 3,
  114. lobby: 0,
  115. })).await.unwrap();
  116. }
  117. pub async fn create_room_with_difficulty<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId, name: &str, password: &str, difficulty: Difficulty) {
  118. ship.handle(id, RecvShipPacket::CreateRoom(CreateRoom {
  119. unknown: [0; 2],
  120. name: utf8_to_utf16_array!(name, 16),
  121. password: utf8_to_utf16_array!(password, 16),
  122. difficulty: difficulty.into(),
  123. battle: 0,
  124. challenge: 0,
  125. episode: 1,
  126. single_player: 0,
  127. padding: [0; 3],
  128. })).await.unwrap();
  129. ship.handle(id, RecvShipPacket::DoneBursting(DoneBursting {})).await.unwrap();
  130. }
  131. pub async fn join_room<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId, room_id: u32) {
  132. ship.handle(id, RecvShipPacket::MenuSelect(MenuSelect {
  133. menu: ROOM_MENU_ID,
  134. item: room_id,
  135. })).await.unwrap();
  136. ship.handle(id, RecvShipPacket::DoneBursting(DoneBursting {})).await.unwrap();
  137. }
  138. pub struct WeaponBuilder {
  139. weapon: item::weapon::WeaponType,
  140. grind: u8,
  141. }
  142. impl WeaponBuilder {
  143. pub fn grind(self, grind: u8) -> WeaponBuilder {
  144. WeaponBuilder {
  145. grind,
  146. ..self
  147. }
  148. }
  149. pub fn as_new(self) -> item::NewItemEntity {
  150. item::NewItemEntity {
  151. item: item::ItemDetail::Weapon(
  152. item::weapon::Weapon {
  153. weapon: self.weapon,
  154. grind: self.grind,
  155. special: None,
  156. attrs: [None, None, None],
  157. tekked: true,
  158. }
  159. )
  160. }
  161. }
  162. }
  163. pub struct ItemBuilder;
  164. impl ItemBuilder {
  165. pub fn weapon(weapon: item::weapon::WeaponType) -> WeaponBuilder {
  166. WeaponBuilder {
  167. weapon,
  168. grind: 0,
  169. }
  170. }
  171. }