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.

987 lines
33 KiB

  1. use elseware::common::serverstate::{ClientId, ServerState};
  2. use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
  3. use elseware::entity::item;
  4. use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket};
  5. use libpso::packet::ship::*;
  6. use libpso::packet::messages::*;
  7. #[path = "common.rs"]
  8. mod common;
  9. use common::*;
  10. #[async_std::test]
  11. async fn test_bank_items_sent_in_character_login() {
  12. let mut entity_gateway = InMemoryGateway::new();
  13. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  14. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  15. entity_gateway.create_item(
  16. item::NewItemEntity {
  17. item: item::ItemDetail::Weapon(
  18. item::weapon::Weapon {
  19. weapon: item::weapon::WeaponType::Vulcan,
  20. grind: 0,
  21. special: None,
  22. attrs: [None, None, None],
  23. tekked: true,
  24. }
  25. ),
  26. location: item::ItemLocation::Bank {
  27. character_id: char1.id,
  28. name: item::BankName("".to_string())
  29. }
  30. }).await;
  31. let mut ship = ShipServerState::new(entity_gateway.clone());
  32. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  33. let packets = ship.handle(ClientId(1), &RecvShipPacket::MenuSelect(MenuSelect {
  34. menu: BLOCK_MENU_ID,
  35. item: 1,
  36. })).await.unwrap().collect::<Vec<_>>();
  37. assert!(matches!(&packets[0], (_, SendShipPacket::FullCharacter(fc)) if fc.character.bank.items[0].data1[0..3] == [0x00, 0x08, 0x04] ));
  38. }
  39. #[async_std::test]
  40. async fn test_request_bank_items() {
  41. let mut entity_gateway = InMemoryGateway::new();
  42. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  43. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  44. for _ in 0..3 {
  45. entity_gateway.create_item(
  46. item::NewItemEntity {
  47. item: item::ItemDetail::Weapon(
  48. item::weapon::Weapon {
  49. weapon: item::weapon::WeaponType::Vulcan,
  50. grind: 0,
  51. special: None,
  52. attrs: [None, None, None],
  53. tekked: true,
  54. }
  55. ),
  56. location: item::ItemLocation::Bank {
  57. character_id: char1.id,
  58. name: item::BankName("".to_string())
  59. }
  60. }).await;
  61. }
  62. let mut ship = ShipServerState::new(entity_gateway.clone());
  63. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  64. join_lobby(&mut ship, ClientId(1)).await;
  65. create_room(&mut ship, ClientId(1), "room", "").await;
  66. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  67. client: 0,
  68. target: 0,
  69. unknown: 0,
  70. })))).await.unwrap().collect::<Vec<_>>();
  71. assert!(matches!(&packets[0], (_, SendShipPacket::BankItemList (bank_item_list))
  72. if bank_item_list.item_count == 3
  73. && bank_item_list.size == 0x18 * 3 + 0x14
  74. && bank_item_list.items[0].data1[0..3] == [0x00, 0x08, 0x04]
  75. && bank_item_list.items[1].data1[0..3] == [0x00, 0x08, 0x04]
  76. && bank_item_list.items[2].data1[0..3] == [0x00, 0x08, 0x04]
  77. ));
  78. }
  79. #[async_std::test]
  80. async fn test_request_stacked_bank_items() {
  81. let mut entity_gateway = InMemoryGateway::new();
  82. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  83. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  84. for _ in 0..3 {
  85. entity_gateway.create_item(
  86. item::NewItemEntity {
  87. item: item::ItemDetail::Tool (
  88. item::tool::Tool {
  89. tool: item::tool::ToolType::Monomate,
  90. }
  91. ),
  92. location: item::ItemLocation::Bank {
  93. character_id: char1.id,
  94. name: item::BankName("".to_string())
  95. }
  96. }).await;
  97. }
  98. let mut ship = ShipServerState::new(entity_gateway.clone());
  99. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  100. join_lobby(&mut ship, ClientId(1)).await;
  101. create_room(&mut ship, ClientId(1), "room", "").await;
  102. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  103. client: 0,
  104. target: 0,
  105. unknown: 0,
  106. })))).await.unwrap().collect::<Vec<_>>();
  107. assert!(matches!(&packets[0], (_, SendShipPacket::BankItemList (bank_item_list))
  108. if bank_item_list.item_count == 1
  109. && bank_item_list.size == 0x18 + 0x14
  110. && bank_item_list.items[0].data1[0..3] == [0x03, 0x00, 0x00]
  111. && bank_item_list.items[0].amount == 3
  112. ));
  113. }
  114. #[async_std::test]
  115. async fn test_request_bank_items_sorted() {
  116. let mut entity_gateway = InMemoryGateway::new();
  117. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  118. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  119. entity_gateway.create_item(
  120. item::NewItemEntity {
  121. item: item::ItemDetail::Weapon(
  122. item::weapon::Weapon {
  123. weapon: item::weapon::WeaponType::Vulcan,
  124. grind: 0,
  125. special: None,
  126. attrs: [None, None, None],
  127. tekked: true,
  128. }
  129. ),
  130. location: item::ItemLocation::Bank {
  131. character_id: char1.id,
  132. name: item::BankName("".to_string())
  133. }
  134. }).await;
  135. entity_gateway.create_item(
  136. item::NewItemEntity {
  137. item: item::ItemDetail::Tool (
  138. item::tool::Tool {
  139. tool: item::tool::ToolType::Monomate,
  140. }
  141. ),
  142. location: item::ItemLocation::Bank {
  143. character_id: char1.id,
  144. name: item::BankName("".to_string())
  145. }
  146. }).await;
  147. entity_gateway.create_item(
  148. item::NewItemEntity {
  149. item: item::ItemDetail::Weapon(
  150. item::weapon::Weapon {
  151. weapon: item::weapon::WeaponType::Calibur,
  152. grind: 0,
  153. special: None,
  154. attrs: [None, None, None],
  155. tekked: true,
  156. }
  157. ),
  158. location: item::ItemLocation::Bank {
  159. character_id: char1.id,
  160. name: item::BankName("".to_string())
  161. }
  162. }).await;
  163. let mut ship = ShipServerState::new(entity_gateway.clone());
  164. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  165. join_lobby(&mut ship, ClientId(1)).await;
  166. create_room(&mut ship, ClientId(1), "room", "").await;
  167. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  168. client: 0,
  169. target: 0,
  170. unknown: 0,
  171. })))).await.unwrap().collect::<Vec<_>>();
  172. assert!(matches!(&packets[0], (_, SendShipPacket::BankItemList (bank_item_list))
  173. if bank_item_list.item_count == 3
  174. && bank_item_list.size == 0x18 * 3 + 0x14
  175. && bank_item_list.items[0].data1[0..3] == [0x00, 0x02, 0x04]
  176. && bank_item_list.items[1].data1[0..3] == [0x00, 0x08, 0x04]
  177. && bank_item_list.items[2].data1[0..3] == [0x03, 0x00, 0x00]
  178. ));
  179. }
  180. #[async_std::test]
  181. async fn test_deposit_individual_item() {
  182. let mut entity_gateway = InMemoryGateway::new();
  183. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  184. entity_gateway.create_item(
  185. item::NewItemEntity {
  186. item: item::ItemDetail::Weapon(
  187. item::weapon::Weapon {
  188. weapon: item::weapon::WeaponType::Saber,
  189. grind: 0,
  190. special: None,
  191. attrs: [None, None, None],
  192. tekked: true,
  193. }
  194. ),
  195. location: item::ItemLocation::Inventory {
  196. character_id: char1.id,
  197. slot: 0,
  198. equipped: false,
  199. }
  200. }).await;
  201. entity_gateway.create_item(
  202. item::NewItemEntity {
  203. item: item::ItemDetail::Weapon(
  204. item::weapon::Weapon {
  205. weapon: item::weapon::WeaponType::Handgun,
  206. grind: 0,
  207. special: None,
  208. attrs: [None, None, None],
  209. tekked: true,
  210. }
  211. ),
  212. location: item::ItemLocation::Inventory {
  213. character_id: char1.id,
  214. slot: 1,
  215. equipped: false,
  216. }
  217. }).await;
  218. let mut ship = ShipServerState::new(entity_gateway.clone());
  219. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  220. join_lobby(&mut ship, ClientId(1)).await;
  221. create_room(&mut ship, ClientId(1), "room", "").await;
  222. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  223. client: 0,
  224. target: 0,
  225. unknown: 0,
  226. })))).await.unwrap().for_each(drop);
  227. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  228. client: 0,
  229. target: 0,
  230. item_id: 0x10001,
  231. action: 0,
  232. item_amount: 0,
  233. meseta_amount: 0,
  234. unknown: 0,
  235. })))).await.unwrap().collect::<Vec<_>>();
  236. assert!(packets.len() == 1);
  237. assert!(matches!(&packets[0], (_, SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  238. if player_no_longer_has_item.item_id == 0x10001
  239. && player_no_longer_has_item.amount == 0
  240. ));
  241. let items = entity_gateway.get_items_by_character(&char1).await;
  242. let bank_item_ids = items.iter()
  243. .filter_map(|item| {
  244. if let item::ItemLocation::Bank {..} = item.location {
  245. Some(item.id)
  246. }
  247. else {
  248. None
  249. }
  250. })
  251. .collect::<Vec<_>>();
  252. assert!(bank_item_ids == vec![item::ItemEntityId(2)]);
  253. }
  254. #[async_std::test]
  255. async fn test_deposit_stacked_item() {
  256. let mut entity_gateway = InMemoryGateway::new();
  257. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  258. for _ in 0..3 {
  259. entity_gateway.create_item(
  260. item::NewItemEntity {
  261. item: item::ItemDetail::Tool(
  262. item::tool::Tool {
  263. tool: item::tool::ToolType::Monomate,
  264. }
  265. ),
  266. location: item::ItemLocation::Inventory {
  267. character_id: char1.id,
  268. slot: 0,
  269. equipped: false,
  270. }
  271. }).await;
  272. }
  273. let mut ship = ShipServerState::new(entity_gateway.clone());
  274. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  275. join_lobby(&mut ship, ClientId(1)).await;
  276. create_room(&mut ship, ClientId(1), "room", "").await;
  277. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  278. client: 0,
  279. target: 0,
  280. unknown: 0,
  281. })))).await.unwrap().for_each(drop);
  282. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  283. client: 0,
  284. target: 0,
  285. item_id: 0x10000,
  286. action: 0,
  287. item_amount: 3,
  288. meseta_amount: 0,
  289. unknown: 0,
  290. })))).await.unwrap().collect::<Vec<_>>();
  291. assert!(packets.len() == 1);
  292. assert!(matches!(&packets[0], (_, SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  293. if player_no_longer_has_item.item_id == 0x10000
  294. && player_no_longer_has_item.amount == 3
  295. ));
  296. let items = entity_gateway.get_items_by_character(&char1).await;
  297. let bank_item_ids = items.iter()
  298. .filter_map(|item| {
  299. if let item::ItemLocation::Bank {..} = item.location {
  300. Some(item.id)
  301. }
  302. else {
  303. None
  304. }
  305. })
  306. .collect::<Vec<_>>();
  307. assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]);
  308. }
  309. #[async_std::test]
  310. async fn test_deposit_partial_stacked_item() {
  311. let mut entity_gateway = InMemoryGateway::new();
  312. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  313. for _ in 0..3 {
  314. entity_gateway.create_item(
  315. item::NewItemEntity {
  316. item: item::ItemDetail::Tool(
  317. item::tool::Tool {
  318. tool: item::tool::ToolType::Monomate,
  319. }
  320. ),
  321. location: item::ItemLocation::Inventory {
  322. character_id: char1.id,
  323. slot: 0,
  324. equipped: false,
  325. }
  326. }).await;
  327. }
  328. let mut ship = ShipServerState::new(entity_gateway.clone());
  329. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  330. join_lobby(&mut ship, ClientId(1)).await;
  331. create_room(&mut ship, ClientId(1), "room", "").await;
  332. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  333. client: 0,
  334. target: 0,
  335. unknown: 0,
  336. })))).await.unwrap().for_each(drop);
  337. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  338. client: 0,
  339. target: 0,
  340. item_id: 0x10000,
  341. action: 0,
  342. item_amount: 2,
  343. meseta_amount: 0,
  344. unknown: 0,
  345. })))).await.unwrap().collect::<Vec<_>>();
  346. assert!(packets.len() == 1);
  347. assert!(matches!(&packets[0], (_, SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  348. if player_no_longer_has_item.item_id == 0x10000
  349. && player_no_longer_has_item.amount == 2
  350. ));
  351. let items = entity_gateway.get_items_by_character(&char1).await;
  352. let bank_item_ids = items.iter()
  353. .filter_map(|item| {
  354. if let item::ItemLocation::Bank {..} = item.location {
  355. Some(item.id)
  356. }
  357. else {
  358. None
  359. }
  360. })
  361. .collect::<Vec<_>>();
  362. assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  363. let inventory_item_ids = items.iter()
  364. .filter_map(|item| {
  365. if let item::ItemLocation::Inventory {..} = item.location {
  366. Some(item.id)
  367. }
  368. else {
  369. None
  370. }
  371. })
  372. .collect::<Vec<_>>();
  373. assert!(inventory_item_ids == vec![item::ItemEntityId(3)]);
  374. }
  375. #[async_std::test]
  376. async fn test_deposit_stacked_item_with_stack_already_in_bank() {
  377. let mut entity_gateway = InMemoryGateway::new();
  378. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  379. for _ in 0..2 {
  380. entity_gateway.create_item(
  381. item::NewItemEntity {
  382. item: item::ItemDetail::Tool(
  383. item::tool::Tool {
  384. tool: item::tool::ToolType::Monomate,
  385. }
  386. ),
  387. location: item::ItemLocation::Inventory {
  388. character_id: char1.id,
  389. slot: 0,
  390. equipped: false,
  391. }
  392. }).await;
  393. entity_gateway.create_item(
  394. item::NewItemEntity {
  395. item: item::ItemDetail::Tool(
  396. item::tool::Tool {
  397. tool: item::tool::ToolType::Monomate,
  398. }
  399. ),
  400. location: item::ItemLocation::Bank {
  401. character_id: char1.id,
  402. name: item::BankName("".into()),
  403. }
  404. }).await;
  405. }
  406. let mut ship = ShipServerState::new(entity_gateway.clone());
  407. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  408. join_lobby(&mut ship, ClientId(1)).await;
  409. create_room(&mut ship, ClientId(1), "room", "").await;
  410. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  411. client: 0,
  412. target: 0,
  413. unknown: 0,
  414. })))).await.unwrap().for_each(drop);
  415. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  416. client: 0,
  417. target: 0,
  418. item_id: 0x10000,
  419. action: 0,
  420. item_amount: 2,
  421. meseta_amount: 0,
  422. unknown: 0,
  423. })))).await.unwrap().collect::<Vec<_>>();
  424. assert!(packets.len() == 1);
  425. assert!(matches!(&packets[0], (_, SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  426. if player_no_longer_has_item.item_id == 0x10000
  427. && player_no_longer_has_item.amount == 2
  428. ));
  429. let items = entity_gateway.get_items_by_character(&char1).await;
  430. let bank_item_ids = items.iter()
  431. .filter_map(|item| {
  432. if let item::ItemLocation::Bank {..} = item.location {
  433. Some(item.id)
  434. }
  435. else {
  436. None
  437. }
  438. })
  439. .collect::<Vec<_>>();
  440. assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)]);
  441. }
  442. #[async_std::test]
  443. async fn test_deposit_stacked_item_with_full_stack_in_bank() {
  444. let mut entity_gateway = InMemoryGateway::new();
  445. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  446. for _ in 0..2 {
  447. entity_gateway.create_item(
  448. item::NewItemEntity {
  449. item: item::ItemDetail::Tool(
  450. item::tool::Tool {
  451. tool: item::tool::ToolType::Monomate,
  452. }
  453. ),
  454. location: item::ItemLocation::Inventory {
  455. character_id: char1.id,
  456. slot: 0,
  457. equipped: false,
  458. }
  459. }).await;
  460. }
  461. for _ in 0..10 {
  462. entity_gateway.create_item(
  463. item::NewItemEntity {
  464. item: item::ItemDetail::Tool(
  465. item::tool::Tool {
  466. tool: item::tool::ToolType::Monomate,
  467. }
  468. ),
  469. location: item::ItemLocation::Bank {
  470. character_id: char1.id,
  471. name: item::BankName("".into()),
  472. }
  473. }).await;
  474. }
  475. let mut ship = ShipServerState::new(entity_gateway.clone());
  476. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  477. join_lobby(&mut ship, ClientId(1)).await;
  478. create_room(&mut ship, ClientId(1), "room", "").await;
  479. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  480. client: 0,
  481. target: 0,
  482. unknown: 0,
  483. })))).await.unwrap().for_each(drop);
  484. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  485. client: 0,
  486. target: 0,
  487. item_id: 0x10000,
  488. action: 0,
  489. item_amount: 2,
  490. meseta_amount: 0,
  491. unknown: 0,
  492. })))).await;
  493. assert!(packets.is_err());
  494. let items = entity_gateway.get_items_by_character(&char1).await;
  495. let bank_item_ids = items.iter()
  496. .filter_map(|item| {
  497. if let item::ItemLocation::Bank {..} = item.location {
  498. Some(item.id)
  499. }
  500. else {
  501. None
  502. }
  503. })
  504. .collect::<Vec<_>>();
  505. assert!(bank_item_ids.len() == 10);
  506. let inventory_item_ids = items.iter()
  507. .filter_map(|item| {
  508. if let item::ItemLocation::Inventory {..} = item.location {
  509. Some(item.id)
  510. }
  511. else {
  512. None
  513. }
  514. })
  515. .collect::<Vec<_>>();
  516. assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  517. }
  518. #[async_std::test]
  519. async fn test_deposit_individual_item_in_full_bank() {
  520. let mut entity_gateway = InMemoryGateway::new();
  521. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  522. entity_gateway.create_item(
  523. item::NewItemEntity {
  524. item: item::ItemDetail::Weapon(
  525. item::weapon::Weapon {
  526. weapon: item::weapon::WeaponType::Vulcan,
  527. grind: 0,
  528. special: None,
  529. attrs: [None, None, None],
  530. tekked: true,
  531. }
  532. ),
  533. location: item::ItemLocation::Inventory {
  534. character_id: char1.id,
  535. slot: 0,
  536. equipped: false,
  537. }
  538. }).await;
  539. for _ in 0..200 {
  540. entity_gateway.create_item(
  541. item::NewItemEntity {
  542. item: item::ItemDetail::Weapon(
  543. item::weapon::Weapon {
  544. weapon: item::weapon::WeaponType::Vulcan,
  545. grind: 0,
  546. special: None,
  547. attrs: [None, None, None],
  548. tekked: true,
  549. }
  550. ),
  551. location: item::ItemLocation::Bank {
  552. character_id: char1.id,
  553. name: item::BankName("".to_string())
  554. }
  555. }).await;
  556. }
  557. let mut ship = ShipServerState::new(entity_gateway.clone());
  558. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  559. join_lobby(&mut ship, ClientId(1)).await;
  560. create_room(&mut ship, ClientId(1), "room", "").await;
  561. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  562. client: 0,
  563. target: 0,
  564. unknown: 0,
  565. })))).await.unwrap().for_each(drop);
  566. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  567. client: 0,
  568. target: 0,
  569. item_id: 0x10000,
  570. action: 0,
  571. item_amount: 0,
  572. meseta_amount: 0,
  573. unknown: 0,
  574. })))).await;
  575. assert!(packets.is_err());
  576. let items = entity_gateway.get_items_by_character(&char1).await;
  577. let bank_item_ids = items.iter()
  578. .filter_map(|item| {
  579. if let item::ItemLocation::Bank {..} = item.location {
  580. Some(item.id)
  581. }
  582. else {
  583. None
  584. }
  585. })
  586. .collect::<Vec<_>>();
  587. assert!(bank_item_ids.len() == 200);
  588. let inventory_item_ids = items.iter()
  589. .filter_map(|item| {
  590. if let item::ItemLocation::Inventory {..} = item.location {
  591. Some(item.id)
  592. }
  593. else {
  594. None
  595. }
  596. })
  597. .collect::<Vec<_>>();
  598. assert!(inventory_item_ids == vec![item::ItemEntityId(1)]);
  599. }
  600. #[async_std::test]
  601. async fn test_deposit_stacked_item_in_full_bank() {
  602. let mut entity_gateway = InMemoryGateway::new();
  603. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  604. for _ in 0..2 {
  605. entity_gateway.create_item(
  606. item::NewItemEntity {
  607. item: item::ItemDetail::Tool(
  608. item::tool::Tool {
  609. tool: item::tool::ToolType::Monomate,
  610. }
  611. ),
  612. location: item::ItemLocation::Inventory {
  613. character_id: char1.id,
  614. slot: 0,
  615. equipped: false,
  616. }
  617. }).await;
  618. }
  619. for _ in 0..200 {
  620. entity_gateway.create_item(
  621. item::NewItemEntity {
  622. item: item::ItemDetail::Weapon(
  623. item::weapon::Weapon {
  624. weapon: item::weapon::WeaponType::Vulcan,
  625. grind: 0,
  626. special: None,
  627. attrs: [None, None, None],
  628. tekked: true,
  629. }
  630. ),
  631. location: item::ItemLocation::Bank {
  632. character_id: char1.id,
  633. name: item::BankName("".to_string())
  634. }
  635. }).await;
  636. }
  637. let mut ship = ShipServerState::new(entity_gateway.clone());
  638. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  639. join_lobby(&mut ship, ClientId(1)).await;
  640. create_room(&mut ship, ClientId(1), "room", "").await;
  641. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  642. client: 0,
  643. target: 0,
  644. unknown: 0,
  645. })))).await.unwrap().for_each(drop);
  646. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  647. client: 0,
  648. target: 0,
  649. item_id: 0x10000,
  650. action: 0,
  651. item_amount: 2,
  652. meseta_amount: 0,
  653. unknown: 0,
  654. })))).await;
  655. assert!(packets.is_err());
  656. let items = entity_gateway.get_items_by_character(&char1).await;
  657. let bank_item_ids = items.iter()
  658. .filter_map(|item| {
  659. if let item::ItemLocation::Bank {..} = item.location {
  660. Some(item.id)
  661. }
  662. else {
  663. None
  664. }
  665. })
  666. .collect::<Vec<_>>();
  667. assert!(bank_item_ids.len() == 200);
  668. let inventory_item_ids = items.iter()
  669. .filter_map(|item| {
  670. if let item::ItemLocation::Inventory {..} = item.location {
  671. Some(item.id)
  672. }
  673. else {
  674. None
  675. }
  676. })
  677. .collect::<Vec<_>>();
  678. assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  679. }
  680. #[async_std::test]
  681. async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() {
  682. let mut entity_gateway = InMemoryGateway::new();
  683. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  684. for _ in 0..2 {
  685. entity_gateway.create_item(
  686. item::NewItemEntity {
  687. item: item::ItemDetail::Tool(
  688. item::tool::Tool {
  689. tool: item::tool::ToolType::Monomate,
  690. }
  691. ),
  692. location: item::ItemLocation::Inventory {
  693. character_id: char1.id,
  694. slot: 0,
  695. equipped: false,
  696. }
  697. }).await;
  698. }
  699. for _ in 0..199 {
  700. entity_gateway.create_item(
  701. item::NewItemEntity {
  702. item: item::ItemDetail::Weapon(
  703. item::weapon::Weapon {
  704. weapon: item::weapon::WeaponType::Vulcan,
  705. grind: 0,
  706. special: None,
  707. attrs: [None, None, None],
  708. tekked: true,
  709. }
  710. ),
  711. location: item::ItemLocation::Bank {
  712. character_id: char1.id,
  713. name: item::BankName("".to_string())
  714. }
  715. }).await;
  716. }
  717. for _ in 0..2 {
  718. entity_gateway.create_item(
  719. item::NewItemEntity {
  720. item: item::ItemDetail::Tool(
  721. item::tool::Tool {
  722. tool: item::tool::ToolType::Monomate,
  723. }
  724. ),
  725. location: item::ItemLocation::Bank {
  726. character_id: char1.id,
  727. name: item::BankName("".to_string())
  728. }
  729. }).await;
  730. }
  731. let mut ship = ShipServerState::new(entity_gateway.clone());
  732. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  733. join_lobby(&mut ship, ClientId(1)).await;
  734. create_room(&mut ship, ClientId(1), "room", "").await;
  735. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  736. client: 0,
  737. target: 0,
  738. unknown: 0,
  739. })))).await.unwrap().for_each(drop);
  740. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  741. client: 0,
  742. target: 0,
  743. item_id: 0x10000,
  744. action: 0,
  745. item_amount: 2,
  746. meseta_amount: 0,
  747. unknown: 0,
  748. })))).await.unwrap().for_each(drop);
  749. let items = entity_gateway.get_items_by_character(&char1).await;
  750. let bank_item_ids = items.iter()
  751. .filter_map(|item| {
  752. if let item::ItemLocation::Bank {..} = item.location {
  753. Some(item.id)
  754. }
  755. else {
  756. None
  757. }
  758. })
  759. .collect::<Vec<_>>();
  760. assert!(bank_item_ids.len() == 203);
  761. let inventory_item_ids = items.iter()
  762. .filter_map(|item| {
  763. if let item::ItemLocation::Inventory {..} = item.location {
  764. Some(item.id)
  765. }
  766. else {
  767. None
  768. }
  769. })
  770. .collect::<Vec<_>>();
  771. assert!(inventory_item_ids.len() == 0);
  772. }
  773. #[async_std::test]
  774. async fn test_deposit_meseta() {
  775. let mut entity_gateway = InMemoryGateway::new();
  776. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  777. char1.meseta = 300;
  778. entity_gateway.save_character(&char1).await;
  779. let mut ship = ShipServerState::new(entity_gateway.clone());
  780. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  781. join_lobby(&mut ship, ClientId(1)).await;
  782. create_room(&mut ship, ClientId(1), "room", "").await;
  783. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  784. client: 0,
  785. target: 0,
  786. unknown: 0,
  787. })))).await.unwrap().for_each(drop);
  788. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  789. client: 0,
  790. target: 0,
  791. item_id: 0xFFFFFFFF,
  792. action: 0,
  793. item_amount: 0,
  794. meseta_amount: 23,
  795. unknown: 0,
  796. })))).await.unwrap().for_each(drop);
  797. let characters = entity_gateway.get_characters_by_user(&user1).await;
  798. let char = characters[0].as_ref().unwrap();
  799. println!("meseta {}", char.meseta);
  800. assert!(char.meseta == 277);
  801. assert!(char.bank_meseta == 23);
  802. }
  803. #[async_std::test]
  804. async fn test_deposit_too_much_meseta() {
  805. let mut entity_gateway = InMemoryGateway::new();
  806. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  807. char1.meseta = 300;
  808. char1.bank_meseta = 999980;
  809. entity_gateway.save_character(&char1).await;
  810. let mut ship = ShipServerState::new(entity_gateway.clone());
  811. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  812. join_lobby(&mut ship, ClientId(1)).await;
  813. create_room(&mut ship, ClientId(1), "room", "").await;
  814. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  815. client: 0,
  816. target: 0,
  817. unknown: 0,
  818. })))).await.unwrap().for_each(drop);
  819. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  820. client: 0,
  821. target: 0,
  822. item_id: 0xFFFFFFFF,
  823. action: 0,
  824. item_amount: 0,
  825. meseta_amount: 23,
  826. unknown: 0,
  827. })))).await.unwrap().for_each(drop);
  828. let characters = entity_gateway.get_characters_by_user(&user1).await;
  829. let char = characters[0].as_ref().unwrap();
  830. println!("meseta {}", char.meseta);
  831. assert!(char.meseta == 300);
  832. assert!(char.bank_meseta == 999980);
  833. }
  834. #[async_std::test]
  835. async fn test_deposit_meseta_when_bank_is_maxed() {
  836. let mut entity_gateway = InMemoryGateway::new();
  837. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  838. char1.meseta = 300;
  839. char1.bank_meseta = 999999;
  840. entity_gateway.save_character(&char1).await;
  841. let mut ship = ShipServerState::new(entity_gateway.clone());
  842. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  843. join_lobby(&mut ship, ClientId(1)).await;
  844. create_room(&mut ship, ClientId(1), "room", "").await;
  845. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  846. client: 0,
  847. target: 0,
  848. unknown: 0,
  849. })))).await.unwrap().for_each(drop);
  850. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  851. client: 0,
  852. target: 0,
  853. item_id: 0xFFFFFFFF,
  854. action: 0,
  855. item_amount: 0,
  856. meseta_amount: 23,
  857. unknown: 0,
  858. })))).await.unwrap().for_each(drop);
  859. let characters = entity_gateway.get_characters_by_user(&user1).await;
  860. let char = characters[0].as_ref().unwrap();
  861. println!("meseta {}", char.meseta);
  862. assert!(char.meseta == 300);
  863. assert!(char.bank_meseta == 999999);
  864. }