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.

1001 lines
34 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. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  185. entity_gateway.create_item(
  186. item::NewItemEntity {
  187. item: item::ItemDetail::Weapon(
  188. item::weapon::Weapon {
  189. weapon: item::weapon::WeaponType::Saber,
  190. grind: 0,
  191. special: None,
  192. attrs: [None, None, None],
  193. tekked: true,
  194. }
  195. ),
  196. location: item::ItemLocation::Inventory {
  197. character_id: char1.id,
  198. slot: 0,
  199. equipped: false,
  200. }
  201. }).await;
  202. entity_gateway.create_item(
  203. item::NewItemEntity {
  204. item: item::ItemDetail::Weapon(
  205. item::weapon::Weapon {
  206. weapon: item::weapon::WeaponType::Handgun,
  207. grind: 0,
  208. special: None,
  209. attrs: [None, None, None],
  210. tekked: true,
  211. }
  212. ),
  213. location: item::ItemLocation::Inventory {
  214. character_id: char1.id,
  215. slot: 1,
  216. equipped: false,
  217. }
  218. }).await;
  219. let mut ship = ShipServerState::new(entity_gateway.clone());
  220. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  221. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  222. join_lobby(&mut ship, ClientId(1)).await;
  223. join_lobby(&mut ship, ClientId(2)).await;
  224. create_room(&mut ship, ClientId(1), "room", "").await;
  225. join_room(&mut ship, ClientId(2), 0).await;
  226. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  227. client: 0,
  228. target: 0,
  229. unknown: 0,
  230. })))).await.unwrap().for_each(drop);
  231. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  232. client: 0,
  233. target: 0,
  234. item_id: 0x10001,
  235. action: 0,
  236. item_amount: 0,
  237. meseta_amount: 0,
  238. unknown: 0,
  239. })))).await.unwrap().collect::<Vec<_>>();
  240. assert!(packets.len() == 1);
  241. assert!(matches!(&packets[0], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  242. if player_no_longer_has_item.item_id == 0x10001
  243. && player_no_longer_has_item.amount == 0
  244. ));
  245. let items = entity_gateway.get_items_by_character(&char1).await;
  246. let bank_item_ids = items.iter()
  247. .filter_map(|item| {
  248. if let item::ItemLocation::Bank {..} = item.location {
  249. Some(item.id)
  250. }
  251. else {
  252. None
  253. }
  254. })
  255. .collect::<Vec<_>>();
  256. assert!(bank_item_ids == vec![item::ItemEntityId(2)]);
  257. }
  258. #[async_std::test]
  259. async fn test_deposit_stacked_item() {
  260. let mut entity_gateway = InMemoryGateway::new();
  261. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  262. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  263. for _ in 0..3 {
  264. entity_gateway.create_item(
  265. item::NewItemEntity {
  266. item: item::ItemDetail::Tool(
  267. item::tool::Tool {
  268. tool: item::tool::ToolType::Monomate,
  269. }
  270. ),
  271. location: item::ItemLocation::Inventory {
  272. character_id: char1.id,
  273. slot: 0,
  274. equipped: false,
  275. }
  276. }).await;
  277. }
  278. let mut ship = ShipServerState::new(entity_gateway.clone());
  279. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  280. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  281. join_lobby(&mut ship, ClientId(1)).await;
  282. join_lobby(&mut ship, ClientId(2)).await;
  283. create_room(&mut ship, ClientId(1), "room", "").await;
  284. join_room(&mut ship, ClientId(2), 0).await;
  285. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  286. client: 0,
  287. target: 0,
  288. unknown: 0,
  289. })))).await.unwrap().for_each(drop);
  290. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  291. client: 0,
  292. target: 0,
  293. item_id: 0x10000,
  294. action: 0,
  295. item_amount: 3,
  296. meseta_amount: 0,
  297. unknown: 0,
  298. })))).await.unwrap().collect::<Vec<_>>();
  299. assert!(packets.len() == 1);
  300. assert!(matches!(&packets[0], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  301. if player_no_longer_has_item.item_id == 0x10000
  302. && player_no_longer_has_item.amount == 3
  303. ));
  304. let items = entity_gateway.get_items_by_character(&char1).await;
  305. let bank_item_ids = items.iter()
  306. .filter_map(|item| {
  307. if let item::ItemLocation::Bank {..} = item.location {
  308. Some(item.id)
  309. }
  310. else {
  311. None
  312. }
  313. })
  314. .collect::<Vec<_>>();
  315. assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]);
  316. }
  317. #[async_std::test]
  318. async fn test_deposit_partial_stacked_item() {
  319. let mut entity_gateway = InMemoryGateway::new();
  320. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  321. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  322. for _ in 0..3 {
  323. entity_gateway.create_item(
  324. item::NewItemEntity {
  325. item: item::ItemDetail::Tool(
  326. item::tool::Tool {
  327. tool: item::tool::ToolType::Monomate,
  328. }
  329. ),
  330. location: item::ItemLocation::Inventory {
  331. character_id: char1.id,
  332. slot: 0,
  333. equipped: false,
  334. }
  335. }).await;
  336. }
  337. let mut ship = ShipServerState::new(entity_gateway.clone());
  338. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  339. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  340. join_lobby(&mut ship, ClientId(1)).await;
  341. join_lobby(&mut ship, ClientId(2)).await;
  342. create_room(&mut ship, ClientId(1), "room", "").await;
  343. join_room(&mut ship, ClientId(2), 0).await;
  344. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  345. client: 0,
  346. target: 0,
  347. unknown: 0,
  348. })))).await.unwrap().for_each(drop);
  349. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  350. client: 0,
  351. target: 0,
  352. item_id: 0x10000,
  353. action: 0,
  354. item_amount: 2,
  355. meseta_amount: 0,
  356. unknown: 0,
  357. })))).await.unwrap().collect::<Vec<_>>();
  358. assert!(packets.len() == 1);
  359. assert!(matches!(&packets[0], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  360. if player_no_longer_has_item.item_id == 0x10000
  361. && player_no_longer_has_item.amount == 2
  362. ));
  363. let items = entity_gateway.get_items_by_character(&char1).await;
  364. let bank_item_ids = items.iter()
  365. .filter_map(|item| {
  366. if let item::ItemLocation::Bank {..} = item.location {
  367. Some(item.id)
  368. }
  369. else {
  370. None
  371. }
  372. })
  373. .collect::<Vec<_>>();
  374. assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  375. let inventory_item_ids = items.iter()
  376. .filter_map(|item| {
  377. if let item::ItemLocation::Inventory {..} = item.location {
  378. Some(item.id)
  379. }
  380. else {
  381. None
  382. }
  383. })
  384. .collect::<Vec<_>>();
  385. assert!(inventory_item_ids == vec![item::ItemEntityId(3)]);
  386. }
  387. #[async_std::test]
  388. async fn test_deposit_stacked_item_with_stack_already_in_bank() {
  389. let mut entity_gateway = InMemoryGateway::new();
  390. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  391. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  392. for _ in 0..2 {
  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::Inventory {
  401. character_id: char1.id,
  402. slot: 0,
  403. equipped: false,
  404. }
  405. }).await;
  406. entity_gateway.create_item(
  407. item::NewItemEntity {
  408. item: item::ItemDetail::Tool(
  409. item::tool::Tool {
  410. tool: item::tool::ToolType::Monomate,
  411. }
  412. ),
  413. location: item::ItemLocation::Bank {
  414. character_id: char1.id,
  415. name: item::BankName("".into()),
  416. }
  417. }).await;
  418. }
  419. let mut ship = ShipServerState::new(entity_gateway.clone());
  420. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  421. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  422. join_lobby(&mut ship, ClientId(1)).await;
  423. join_lobby(&mut ship, ClientId(2)).await;
  424. create_room(&mut ship, ClientId(1), "room", "").await;
  425. join_room(&mut ship, ClientId(2), 0).await;
  426. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  427. client: 0,
  428. target: 0,
  429. unknown: 0,
  430. })))).await.unwrap().for_each(drop);
  431. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  432. client: 0,
  433. target: 0,
  434. item_id: 0x10000,
  435. action: 0,
  436. item_amount: 2,
  437. meseta_amount: 0,
  438. unknown: 0,
  439. })))).await.unwrap().collect::<Vec<_>>();
  440. assert!(packets.len() == 1);
  441. assert!(matches!(&packets[0], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  442. if player_no_longer_has_item.item_id == 0x10000
  443. && player_no_longer_has_item.amount == 2
  444. ));
  445. let items = entity_gateway.get_items_by_character(&char1).await;
  446. let bank_item_ids = items.iter()
  447. .filter_map(|item| {
  448. if let item::ItemLocation::Bank {..} = item.location {
  449. Some(item.id)
  450. }
  451. else {
  452. None
  453. }
  454. })
  455. .collect::<Vec<_>>();
  456. assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)]);
  457. }
  458. #[async_std::test]
  459. async fn test_deposit_stacked_item_with_full_stack_in_bank() {
  460. let mut entity_gateway = InMemoryGateway::new();
  461. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  462. for _ in 0..2 {
  463. entity_gateway.create_item(
  464. item::NewItemEntity {
  465. item: item::ItemDetail::Tool(
  466. item::tool::Tool {
  467. tool: item::tool::ToolType::Monomate,
  468. }
  469. ),
  470. location: item::ItemLocation::Inventory {
  471. character_id: char1.id,
  472. slot: 0,
  473. equipped: false,
  474. }
  475. }).await;
  476. }
  477. for _ in 0..10 {
  478. entity_gateway.create_item(
  479. item::NewItemEntity {
  480. item: item::ItemDetail::Tool(
  481. item::tool::Tool {
  482. tool: item::tool::ToolType::Monomate,
  483. }
  484. ),
  485. location: item::ItemLocation::Bank {
  486. character_id: char1.id,
  487. name: item::BankName("".into()),
  488. }
  489. }).await;
  490. }
  491. let mut ship = ShipServerState::new(entity_gateway.clone());
  492. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  493. join_lobby(&mut ship, ClientId(1)).await;
  494. create_room(&mut ship, ClientId(1), "room", "").await;
  495. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  496. client: 0,
  497. target: 0,
  498. unknown: 0,
  499. })))).await.unwrap().for_each(drop);
  500. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  501. client: 0,
  502. target: 0,
  503. item_id: 0x10000,
  504. action: 0,
  505. item_amount: 2,
  506. meseta_amount: 0,
  507. unknown: 0,
  508. })))).await;
  509. assert!(packets.is_err());
  510. let items = entity_gateway.get_items_by_character(&char1).await;
  511. let bank_item_ids = items.iter()
  512. .filter_map(|item| {
  513. if let item::ItemLocation::Bank {..} = item.location {
  514. Some(item.id)
  515. }
  516. else {
  517. None
  518. }
  519. })
  520. .collect::<Vec<_>>();
  521. assert!(bank_item_ids.len() == 10);
  522. let inventory_item_ids = items.iter()
  523. .filter_map(|item| {
  524. if let item::ItemLocation::Inventory {..} = item.location {
  525. Some(item.id)
  526. }
  527. else {
  528. None
  529. }
  530. })
  531. .collect::<Vec<_>>();
  532. assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  533. }
  534. #[async_std::test]
  535. async fn test_deposit_individual_item_in_full_bank() {
  536. let mut entity_gateway = InMemoryGateway::new();
  537. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  538. entity_gateway.create_item(
  539. item::NewItemEntity {
  540. item: item::ItemDetail::Weapon(
  541. item::weapon::Weapon {
  542. weapon: item::weapon::WeaponType::Vulcan,
  543. grind: 0,
  544. special: None,
  545. attrs: [None, None, None],
  546. tekked: true,
  547. }
  548. ),
  549. location: item::ItemLocation::Inventory {
  550. character_id: char1.id,
  551. slot: 0,
  552. equipped: false,
  553. }
  554. }).await;
  555. for _ in 0..200 {
  556. entity_gateway.create_item(
  557. item::NewItemEntity {
  558. item: item::ItemDetail::Weapon(
  559. item::weapon::Weapon {
  560. weapon: item::weapon::WeaponType::Vulcan,
  561. grind: 0,
  562. special: None,
  563. attrs: [None, None, None],
  564. tekked: true,
  565. }
  566. ),
  567. location: item::ItemLocation::Bank {
  568. character_id: char1.id,
  569. name: item::BankName("".to_string())
  570. }
  571. }).await;
  572. }
  573. let mut ship = ShipServerState::new(entity_gateway.clone());
  574. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  575. join_lobby(&mut ship, ClientId(1)).await;
  576. create_room(&mut ship, ClientId(1), "room", "").await;
  577. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  578. client: 0,
  579. target: 0,
  580. unknown: 0,
  581. })))).await.unwrap().for_each(drop);
  582. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  583. client: 0,
  584. target: 0,
  585. item_id: 0x10000,
  586. action: 0,
  587. item_amount: 0,
  588. meseta_amount: 0,
  589. unknown: 0,
  590. })))).await;
  591. assert!(packets.is_err());
  592. let items = entity_gateway.get_items_by_character(&char1).await;
  593. let bank_item_ids = items.iter()
  594. .filter_map(|item| {
  595. if let item::ItemLocation::Bank {..} = item.location {
  596. Some(item.id)
  597. }
  598. else {
  599. None
  600. }
  601. })
  602. .collect::<Vec<_>>();
  603. assert!(bank_item_ids.len() == 200);
  604. let inventory_item_ids = items.iter()
  605. .filter_map(|item| {
  606. if let item::ItemLocation::Inventory {..} = item.location {
  607. Some(item.id)
  608. }
  609. else {
  610. None
  611. }
  612. })
  613. .collect::<Vec<_>>();
  614. assert!(inventory_item_ids == vec![item::ItemEntityId(1)]);
  615. }
  616. #[async_std::test]
  617. async fn test_deposit_stacked_item_in_full_bank() {
  618. let mut entity_gateway = InMemoryGateway::new();
  619. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  620. for _ in 0..2 {
  621. entity_gateway.create_item(
  622. item::NewItemEntity {
  623. item: item::ItemDetail::Tool(
  624. item::tool::Tool {
  625. tool: item::tool::ToolType::Monomate,
  626. }
  627. ),
  628. location: item::ItemLocation::Inventory {
  629. character_id: char1.id,
  630. slot: 0,
  631. equipped: false,
  632. }
  633. }).await;
  634. }
  635. for _ in 0..200 {
  636. entity_gateway.create_item(
  637. item::NewItemEntity {
  638. item: item::ItemDetail::Weapon(
  639. item::weapon::Weapon {
  640. weapon: item::weapon::WeaponType::Vulcan,
  641. grind: 0,
  642. special: None,
  643. attrs: [None, None, None],
  644. tekked: true,
  645. }
  646. ),
  647. location: item::ItemLocation::Bank {
  648. character_id: char1.id,
  649. name: item::BankName("".to_string())
  650. }
  651. }).await;
  652. }
  653. let mut ship = ShipServerState::new(entity_gateway.clone());
  654. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  655. join_lobby(&mut ship, ClientId(1)).await;
  656. create_room(&mut ship, ClientId(1), "room", "").await;
  657. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  658. client: 0,
  659. target: 0,
  660. unknown: 0,
  661. })))).await.unwrap().for_each(drop);
  662. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  663. client: 0,
  664. target: 0,
  665. item_id: 0x10000,
  666. action: 0,
  667. item_amount: 2,
  668. meseta_amount: 0,
  669. unknown: 0,
  670. })))).await;
  671. assert!(packets.is_err());
  672. let items = entity_gateway.get_items_by_character(&char1).await;
  673. let bank_item_ids = items.iter()
  674. .filter_map(|item| {
  675. if let item::ItemLocation::Bank {..} = item.location {
  676. Some(item.id)
  677. }
  678. else {
  679. None
  680. }
  681. })
  682. .collect::<Vec<_>>();
  683. assert!(bank_item_ids.len() == 200);
  684. let inventory_item_ids = items.iter()
  685. .filter_map(|item| {
  686. if let item::ItemLocation::Inventory {..} = item.location {
  687. Some(item.id)
  688. }
  689. else {
  690. None
  691. }
  692. })
  693. .collect::<Vec<_>>();
  694. assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  695. }
  696. #[async_std::test]
  697. async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() {
  698. let mut entity_gateway = InMemoryGateway::new();
  699. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  700. for _ in 0..2 {
  701. entity_gateway.create_item(
  702. item::NewItemEntity {
  703. item: item::ItemDetail::Tool(
  704. item::tool::Tool {
  705. tool: item::tool::ToolType::Monomate,
  706. }
  707. ),
  708. location: item::ItemLocation::Inventory {
  709. character_id: char1.id,
  710. slot: 0,
  711. equipped: false,
  712. }
  713. }).await;
  714. }
  715. for _ in 0..199 {
  716. entity_gateway.create_item(
  717. item::NewItemEntity {
  718. item: item::ItemDetail::Weapon(
  719. item::weapon::Weapon {
  720. weapon: item::weapon::WeaponType::Vulcan,
  721. grind: 0,
  722. special: None,
  723. attrs: [None, None, None],
  724. tekked: true,
  725. }
  726. ),
  727. location: item::ItemLocation::Bank {
  728. character_id: char1.id,
  729. name: item::BankName("".to_string())
  730. }
  731. }).await;
  732. }
  733. for _ in 0..2 {
  734. entity_gateway.create_item(
  735. item::NewItemEntity {
  736. item: item::ItemDetail::Tool(
  737. item::tool::Tool {
  738. tool: item::tool::ToolType::Monomate,
  739. }
  740. ),
  741. location: item::ItemLocation::Bank {
  742. character_id: char1.id,
  743. name: item::BankName("".to_string())
  744. }
  745. }).await;
  746. }
  747. let mut ship = ShipServerState::new(entity_gateway.clone());
  748. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  749. join_lobby(&mut ship, ClientId(1)).await;
  750. create_room(&mut ship, ClientId(1), "room", "").await;
  751. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  752. client: 0,
  753. target: 0,
  754. unknown: 0,
  755. })))).await.unwrap().for_each(drop);
  756. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  757. client: 0,
  758. target: 0,
  759. item_id: 0x10000,
  760. action: 0,
  761. item_amount: 2,
  762. meseta_amount: 0,
  763. unknown: 0,
  764. })))).await.unwrap().for_each(drop);
  765. let items = entity_gateway.get_items_by_character(&char1).await;
  766. let bank_item_ids = items.iter()
  767. .filter_map(|item| {
  768. if let item::ItemLocation::Bank {..} = item.location {
  769. Some(item.id)
  770. }
  771. else {
  772. None
  773. }
  774. })
  775. .collect::<Vec<_>>();
  776. assert!(bank_item_ids.len() == 203);
  777. let inventory_item_ids = items.iter()
  778. .filter_map(|item| {
  779. if let item::ItemLocation::Inventory {..} = item.location {
  780. Some(item.id)
  781. }
  782. else {
  783. None
  784. }
  785. })
  786. .collect::<Vec<_>>();
  787. assert!(inventory_item_ids.len() == 0);
  788. }
  789. #[async_std::test]
  790. async fn test_deposit_meseta() {
  791. let mut entity_gateway = InMemoryGateway::new();
  792. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  793. char1.meseta = 300;
  794. entity_gateway.save_character(&char1).await;
  795. let mut ship = ShipServerState::new(entity_gateway.clone());
  796. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  797. join_lobby(&mut ship, ClientId(1)).await;
  798. create_room(&mut ship, ClientId(1), "room", "").await;
  799. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  800. client: 0,
  801. target: 0,
  802. unknown: 0,
  803. })))).await.unwrap().for_each(drop);
  804. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  805. client: 0,
  806. target: 0,
  807. item_id: 0xFFFFFFFF,
  808. action: 0,
  809. item_amount: 0,
  810. meseta_amount: 23,
  811. unknown: 0,
  812. })))).await.unwrap().for_each(drop);
  813. let characters = entity_gateway.get_characters_by_user(&user1).await;
  814. let char = characters[0].as_ref().unwrap();
  815. assert!(char.meseta == 277);
  816. assert!(char.bank_meseta == 23);
  817. }
  818. #[async_std::test]
  819. async fn test_deposit_too_much_meseta() {
  820. let mut entity_gateway = InMemoryGateway::new();
  821. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  822. char1.meseta = 300;
  823. char1.bank_meseta = 999980;
  824. entity_gateway.save_character(&char1).await;
  825. let mut ship = ShipServerState::new(entity_gateway.clone());
  826. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  827. join_lobby(&mut ship, ClientId(1)).await;
  828. create_room(&mut ship, ClientId(1), "room", "").await;
  829. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  830. client: 0,
  831. target: 0,
  832. unknown: 0,
  833. })))).await.unwrap().for_each(drop);
  834. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  835. client: 0,
  836. target: 0,
  837. item_id: 0xFFFFFFFF,
  838. action: 0,
  839. item_amount: 0,
  840. meseta_amount: 23,
  841. unknown: 0,
  842. })))).await.unwrap().for_each(drop);
  843. let characters = entity_gateway.get_characters_by_user(&user1).await;
  844. let char = characters[0].as_ref().unwrap();
  845. assert!(char.meseta == 300);
  846. assert!(char.bank_meseta == 999980);
  847. }
  848. #[async_std::test]
  849. async fn test_deposit_meseta_when_bank_is_maxed() {
  850. let mut entity_gateway = InMemoryGateway::new();
  851. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  852. char1.meseta = 300;
  853. char1.bank_meseta = 999999;
  854. entity_gateway.save_character(&char1).await;
  855. let mut ship = ShipServerState::new(entity_gateway.clone());
  856. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  857. join_lobby(&mut ship, ClientId(1)).await;
  858. create_room(&mut ship, ClientId(1), "room", "").await;
  859. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  860. client: 0,
  861. target: 0,
  862. unknown: 0,
  863. })))).await.unwrap().for_each(drop);
  864. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  865. client: 0,
  866. target: 0,
  867. item_id: 0xFFFFFFFF,
  868. action: 0,
  869. item_amount: 0,
  870. meseta_amount: 23,
  871. unknown: 0,
  872. })))).await.unwrap().for_each(drop);
  873. let characters = entity_gateway.get_characters_by_user(&user1).await;
  874. let char = characters[0].as_ref().unwrap();
  875. println!("meseta {}", char.meseta);
  876. assert!(char.meseta == 300);
  877. assert!(char.bank_meseta == 999999);
  878. }