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.

453 lines
12 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};
  6. use libpso::character::SectionID;
  7. use entity::item::{Meseta, BankIdentifier};
  8. use ship_server::{ShipServerState, ShipServerStateBuilder, RecvShipPacket};
  9. use maps::room::{RoomMode, Difficulty, Episode};
  10. use maps::area::MapArea;
  11. use maps::maps::null_free_roam_maps;
  12. use maps::object::MapObject;
  13. use maps::monster::MonsterType;
  14. use quests::{QuestList, QuestLoadError};
  15. use drops::{DropTable, ItemDropType};
  16. use shops::{ItemShops, WeaponShopItem, ToolShopItem, ArmorShopItem};
  17. use entity::item;
  18. use libpso::item::weapon;
  19. use libpso::packet::ship::*;
  20. use libpso::packet::login::{Login, Session};
  21. use libpso::util::{utf8_to_array, utf8_to_utf16_array};
  22. fn null_quest_builder(_mode: RoomMode) -> Result<QuestList, QuestLoadError> {
  23. Ok(Default::default())
  24. }
  25. struct NullDropTable;
  26. impl DropTable for NullDropTable {
  27. fn get_drop(&mut self, _map_area: &MapArea, _monster: &MonsterType) -> Option<ItemDropType> {
  28. None
  29. }
  30. fn get_box_drop(&mut self, _map_area: &MapArea, _object: &MapObject) -> Option<ItemDropType> {
  31. None
  32. }
  33. }
  34. pub fn null_drop_table_builder(_episode: Episode, _difficult: Difficulty, _section_id: SectionID) -> Box<dyn DropTable + Send + Sync> {
  35. Box::new(NullDropTable)
  36. }
  37. struct NullItemShops;
  38. #[async_trait::async_trait]
  39. impl ItemShops for NullItemShops {
  40. async fn generate_weapon_list(&self, _difficulty: Difficulty, _section_id: SectionID, _char_level: usize) -> Option<Vec<WeaponShopItem>> {
  41. Some(Vec::new())
  42. }
  43. async fn generate_tool_list(&self, _char_level: usize) -> Vec<ToolShopItem> {
  44. Vec::new()
  45. }
  46. async fn generate_armor_list(&self, _char_level: usize) -> Vec<ArmorShopItem> {
  47. Vec::new()
  48. }
  49. }
  50. pub fn standard_ship_buildable<EG: EntityGateway + Clone>(gateway: EG) -> ShipServerStateBuilder<EG> {
  51. ShipServerState::builder()
  52. .gateway(gateway)
  53. .standard_quest_builder(Box::new(null_quest_builder))
  54. .government_quest_builder(Box::new(null_quest_builder))
  55. .drop_table_builder(Box::new(null_drop_table_builder))
  56. .map_builder(Box::new(null_free_roam_maps))
  57. .item_shops(NullItemShops)
  58. }
  59. pub fn standard_ship<EG: EntityGateway + Clone>(gateway: EG) -> ShipServerState<EG> {
  60. ShipServerState::builder()
  61. .gateway(gateway)
  62. .standard_quest_builder(Box::new(null_quest_builder))
  63. .government_quest_builder(Box::new(null_quest_builder))
  64. .drop_table_builder(Box::new(null_drop_table_builder))
  65. .map_builder(Box::new(null_free_roam_maps))
  66. .item_shops(NullItemShops)
  67. .build()
  68. }
  69. //TODO: remove kb_conf_preset
  70. pub async fn new_user_character<EG: EntityGateway + Clone>(entity_gateway: &mut EG, username: &str, password: &str) -> (UserAccountEntity, CharacterEntity) {
  71. let new_user = NewUserAccountEntity {
  72. email: format!("{}@pso.com", username),
  73. username: username.into(),
  74. password: bcrypt::hash(password, 5).unwrap(),
  75. guildcard: 1,
  76. activated: true,
  77. ..NewUserAccountEntity::default()
  78. };
  79. let user = entity_gateway.create_user(new_user).await.unwrap();
  80. let new_settings = NewUserSettingsEntity::new(user.id);
  81. let _settings = entity_gateway.create_user_settings(new_settings).await.unwrap();
  82. let new_character = NewCharacterEntity::new(user.id);
  83. let character = entity_gateway.create_character(new_character).await.unwrap();
  84. entity_gateway.set_character_meseta(&character.id, Meseta(0)).await.unwrap();
  85. entity_gateway.set_bank_meseta(&character.id, &BankIdentifier::Character, Meseta(0)).await.unwrap();
  86. (user, character)
  87. }
  88. pub async fn log_in_char<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId, username: &str, password: &str) {
  89. let username = username.to_string();
  90. let password = password.to_string();
  91. ship.handle(id, RecvShipPacket::Login(Login {
  92. tag: 0,
  93. guildcard: 0,
  94. version: 0,
  95. unknown1: [0; 6],
  96. team: 0,
  97. username: utf8_to_array(&username),
  98. unknown2: [0; 32],
  99. password: utf8_to_array(&password),
  100. unknown3: [0; 40],
  101. hwinfo: [0; 8],
  102. session: Session::default(),
  103. })).await.unwrap();
  104. }
  105. pub async fn join_lobby<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId) {
  106. ship.handle(id, RecvShipPacket::CharData(CharData {
  107. _unknown: [0; 0x828]
  108. })).await.unwrap();
  109. }
  110. pub async fn create_room<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId, name: &str, password: &str) {
  111. create_room_with_difficulty(ship, id, name, password, Difficulty::Normal).await;
  112. }
  113. pub async fn leave_room<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId) {
  114. ship.handle(id, RecvShipPacket::LobbySelect(LobbySelect {
  115. menu: 3,
  116. lobby: 0,
  117. })).await.unwrap();
  118. }
  119. pub async fn create_room_with_difficulty<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId, name: &str, password: &str, difficulty: Difficulty) {
  120. ship.handle(id, RecvShipPacket::CreateRoom(CreateRoom {
  121. unknown: [0; 2],
  122. name: utf8_to_utf16_array(name),
  123. password: utf8_to_utf16_array(password),
  124. difficulty: difficulty.into(),
  125. battle: 0,
  126. challenge: 0,
  127. episode: 1,
  128. single_player: 0,
  129. padding: [0; 3],
  130. })).await.unwrap();
  131. ship.handle(id, RecvShipPacket::DoneBursting(DoneBursting {})).await.unwrap();
  132. }
  133. pub async fn join_room<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>, id: ClientId, room_id: u32) {
  134. ship.handle(id, RecvShipPacket::MenuSelect(MenuSelect {
  135. menu: ROOM_MENU_ID,
  136. item: room_id,
  137. })).await.unwrap();
  138. ship.handle(id, RecvShipPacket::DoneBursting(DoneBursting {})).await.unwrap();
  139. }
  140. pub struct WeaponBuilder {
  141. weapon: weapon::WeaponType,
  142. grind: u8,
  143. special: Option<weapon::WeaponSpecial>,
  144. attributes: [Option<weapon::WeaponAttribute>; 3],
  145. tekked: bool,
  146. }
  147. impl WeaponBuilder {
  148. fn new(weapon: weapon::WeaponType) -> WeaponBuilder {
  149. WeaponBuilder {
  150. weapon,
  151. grind: 0,
  152. special: None,
  153. attributes: [None; 3],
  154. tekked: true,
  155. }
  156. }
  157. pub fn grind(self, grind: u8) -> WeaponBuilder {
  158. WeaponBuilder {
  159. grind,
  160. ..self
  161. }
  162. }
  163. pub fn special(self, special: weapon::WeaponSpecial) -> WeaponBuilder {
  164. WeaponBuilder {
  165. special: Some(special),
  166. ..self
  167. }
  168. }
  169. pub fn attr(mut self, attr: weapon::Attribute, value: i8) -> WeaponBuilder {
  170. self.attributes
  171. .iter_mut()
  172. .find(|k| k.is_none())
  173. .map(|empty_attr| {
  174. *empty_attr = Some(weapon::WeaponAttribute {
  175. attr,
  176. value,
  177. })
  178. });
  179. self
  180. }
  181. pub fn untekked(self) -> WeaponBuilder {
  182. WeaponBuilder {
  183. tekked: false,
  184. ..self
  185. }
  186. }
  187. pub fn as_new(self) -> item::NewItemEntity {
  188. item::NewItemEntity {
  189. item: item::ItemDetail::Weapon(
  190. weapon::Weapon {
  191. weapon: self.weapon,
  192. grind: self.grind,
  193. special: self.special,
  194. attrs: self.attributes,
  195. tekked: self.tekked,
  196. }
  197. )
  198. }
  199. }
  200. }
  201. pub struct ArmorBuilder {
  202. armor: item::armor::ArmorType,
  203. dfp: u8,
  204. evp: u8,
  205. slots: u8,
  206. }
  207. impl ArmorBuilder {
  208. pub fn new(armor: item::armor::ArmorType) -> ArmorBuilder {
  209. ArmorBuilder {
  210. armor: armor,
  211. dfp: 0,
  212. evp: 0,
  213. slots: 0,
  214. }
  215. }
  216. pub fn slots(self, slots: u8) -> ArmorBuilder {
  217. ArmorBuilder {
  218. slots,
  219. ..self
  220. }
  221. }
  222. pub fn dfp(self, dfp: u8) -> ArmorBuilder {
  223. ArmorBuilder {
  224. dfp,
  225. ..self
  226. }
  227. }
  228. pub fn evp(self, evp: u8) -> ArmorBuilder {
  229. ArmorBuilder {
  230. evp,
  231. ..self
  232. }
  233. }
  234. pub fn as_new(self) -> item::NewItemEntity {
  235. item::NewItemEntity {
  236. item: item::ItemDetail::Armor(
  237. item::armor::Armor {
  238. armor: self.armor,
  239. dfp: self.dfp,
  240. evp: self.evp,
  241. slots: self.slots,
  242. }
  243. )
  244. }
  245. }
  246. }
  247. pub struct ShieldBuilder {
  248. shield: item::shield::ShieldType,
  249. dfp: u8,
  250. evp: u8,
  251. }
  252. impl ShieldBuilder {
  253. pub fn new(shield: item::shield::ShieldType) -> ShieldBuilder {
  254. ShieldBuilder {
  255. shield: shield,
  256. dfp: 0,
  257. evp: 0,
  258. }
  259. }
  260. pub fn dfp(self, dfp: u8) -> ShieldBuilder {
  261. ShieldBuilder {
  262. dfp,
  263. ..self
  264. }
  265. }
  266. pub fn evp(self, evp: u8) -> ShieldBuilder {
  267. ShieldBuilder {
  268. evp,
  269. ..self
  270. }
  271. }
  272. pub fn as_new(self) -> item::NewItemEntity {
  273. item::NewItemEntity {
  274. item: item::ItemDetail::Shield(
  275. item::shield::Shield {
  276. shield: self.shield,
  277. dfp: self.dfp,
  278. evp: self.evp,
  279. }
  280. )
  281. }
  282. }
  283. }
  284. pub struct UnitBuilder {
  285. unit: item::unit::UnitType,
  286. modifier: Option<item::unit::UnitModifier>,
  287. }
  288. impl UnitBuilder {
  289. pub fn modifier(self, modifier: item::unit::UnitModifier) -> UnitBuilder {
  290. UnitBuilder {
  291. modifier: Some(modifier),
  292. ..self
  293. }
  294. }
  295. pub fn as_new(self) -> item::NewItemEntity {
  296. item::NewItemEntity {
  297. item: item::ItemDetail::Unit(
  298. item::unit::Unit {
  299. unit: self.unit,
  300. modifier: self.modifier,
  301. }
  302. )
  303. }
  304. }
  305. }
  306. pub struct MagBuilder {
  307. }
  308. impl MagBuilder {
  309. pub fn as_new(self) -> item::NewItemEntity {
  310. item::NewItemEntity {
  311. item: item::ItemDetail::Mag(
  312. item::mag::Mag::baby_mag(0)
  313. )
  314. }
  315. }
  316. }
  317. pub struct ToolBuilder {
  318. tool: item::tool::ToolType,
  319. }
  320. impl ToolBuilder {
  321. pub fn as_new(self) -> item::NewItemEntity {
  322. item::NewItemEntity {
  323. item: item::ItemDetail::Tool (
  324. item::tool::Tool {
  325. tool: self.tool,
  326. }
  327. ),
  328. }
  329. }
  330. }
  331. pub struct TechBuilder {
  332. tech: item::tech::Technique,
  333. level: u32,
  334. }
  335. impl TechBuilder {
  336. pub fn level(self, level: u32) -> TechBuilder {
  337. TechBuilder {
  338. level,
  339. ..self
  340. }
  341. }
  342. pub fn as_new(self) -> item::NewItemEntity {
  343. item::NewItemEntity {
  344. item: item::ItemDetail::TechniqueDisk (
  345. item::tech::TechniqueDisk {
  346. tech: self.tech,
  347. level: self.level,
  348. }
  349. )
  350. }
  351. }
  352. }
  353. pub struct ItemBuilder;
  354. impl ItemBuilder {
  355. pub fn weapon(weapon: weapon::WeaponType) -> WeaponBuilder {
  356. WeaponBuilder::new(weapon)
  357. }
  358. pub fn armor(armor: item::armor::ArmorType) -> ArmorBuilder {
  359. ArmorBuilder::new(armor)
  360. }
  361. pub fn shield(shield: item::shield::ShieldType) -> ShieldBuilder {
  362. ShieldBuilder::new(shield)
  363. }
  364. pub fn unit(unit: item::unit::UnitType) -> UnitBuilder {
  365. UnitBuilder {
  366. unit: unit,
  367. modifier: None,
  368. }
  369. }
  370. pub fn baby_mag() -> MagBuilder {
  371. MagBuilder {
  372. }
  373. }
  374. pub fn tool(tool: item::tool::ToolType) -> ToolBuilder {
  375. ToolBuilder {
  376. tool: tool,
  377. }
  378. }
  379. pub fn tech(tech: item::tech::Technique) -> TechBuilder {
  380. TechBuilder {
  381. tech: tech,
  382. level: 0,
  383. }
  384. }
  385. }