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.

452 lines
12 KiB

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