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.

1635 lines
62 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
  1. use std::collections::BTreeSet;
  2. use elseware::common::serverstate::{ClientId, ServerState};
  3. use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
  4. use elseware::entity::item;
  5. use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket};
  6. use libpso::packet::ship::*;
  7. use libpso::packet::messages::*;
  8. #[path = "common.rs"]
  9. mod common;
  10. use common::*;
  11. #[async_std::test]
  12. async fn test_bank_items_sent_in_character_login() {
  13. let mut entity_gateway = InMemoryGateway::default();
  14. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  15. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  16. let item = entity_gateway.create_item(
  17. item::NewItemEntity {
  18. item: item::ItemDetail::Weapon(
  19. item::weapon::Weapon {
  20. weapon: item::weapon::WeaponType::Vulcan,
  21. grind: 0,
  22. special: None,
  23. attrs: [None, None, None],
  24. tekked: true,
  25. }
  26. ),
  27. }).await.unwrap();
  28. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![item]), &item::BankIdentifier::Character).await.unwrap();
  29. let mut ship = Box::new(ShipServerState::builder()
  30. .gateway(entity_gateway.clone())
  31. .build());
  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();
  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::default();
  42. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  43. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  44. let mut bank = Vec::new();
  45. for _ in 0..3 {
  46. bank.push(entity_gateway.create_item(
  47. item::NewItemEntity {
  48. item: item::ItemDetail::Weapon(
  49. item::weapon::Weapon {
  50. weapon: item::weapon::WeaponType::Vulcan,
  51. grind: 0,
  52. special: None,
  53. attrs: [None, None, None],
  54. tekked: true,
  55. }
  56. ),
  57. }).await.unwrap());
  58. }
  59. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap();
  60. let mut ship = Box::new(ShipServerState::builder()
  61. .gateway(entity_gateway.clone())
  62. .build());
  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();
  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::default();
  82. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  83. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  84. let mut monomates = Vec::new();
  85. for _ in 0..3usize {
  86. monomates.push(entity_gateway.create_item(
  87. item::NewItemEntity {
  88. item: item::ItemDetail::Tool (
  89. item::tool::Tool {
  90. tool: item::tool::ToolType::Monomate,
  91. }
  92. ),
  93. }).await.unwrap());
  94. }
  95. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap();
  96. let mut ship = Box::new(ShipServerState::builder()
  97. .gateway(entity_gateway.clone())
  98. .build());
  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();
  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::default();
  117. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  118. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  119. let item1 = 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. }).await.unwrap();
  131. let monomate = entity_gateway.create_item(
  132. item::NewItemEntity {
  133. item: item::ItemDetail::Tool (
  134. item::tool::Tool {
  135. tool: item::tool::ToolType::Monomate,
  136. }
  137. ),
  138. }).await.unwrap();
  139. let item2 = entity_gateway.create_item(
  140. item::NewItemEntity {
  141. item: item::ItemDetail::Weapon(
  142. item::weapon::Weapon {
  143. weapon: item::weapon::WeaponType::Calibur,
  144. grind: 0,
  145. special: None,
  146. attrs: [None, None, None],
  147. tekked: true,
  148. }
  149. ),
  150. }).await.unwrap();
  151. let bank = vec![item::BankItemEntity::Individual(item1), vec![monomate].into(), item2.into()];
  152. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap();
  153. let mut ship = Box::new(ShipServerState::builder()
  154. .gateway(entity_gateway.clone())
  155. .build());
  156. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  157. join_lobby(&mut ship, ClientId(1)).await;
  158. create_room(&mut ship, ClientId(1), "room", "").await;
  159. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  160. client: 0,
  161. target: 0,
  162. unknown: 0,
  163. })))).await.unwrap();
  164. assert!(matches!(&packets[0], (_, SendShipPacket::BankItemList (bank_item_list))
  165. if bank_item_list.item_count == 3
  166. && bank_item_list.size == 0x18 * 3 + 0x14
  167. && bank_item_list.items[0].data1[0..3] == [0x00, 0x02, 0x04]
  168. && bank_item_list.items[1].data1[0..3] == [0x00, 0x08, 0x04]
  169. && bank_item_list.items[2].data1[0..3] == [0x03, 0x00, 0x00]
  170. ));
  171. }
  172. #[async_std::test]
  173. async fn test_deposit_individual_item() {
  174. let mut entity_gateway = InMemoryGateway::default();
  175. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  176. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  177. let item0 = entity_gateway.create_item(
  178. item::NewItemEntity {
  179. item: item::ItemDetail::Weapon(
  180. item::weapon::Weapon {
  181. weapon: item::weapon::WeaponType::Saber,
  182. grind: 0,
  183. special: None,
  184. attrs: [None, None, None],
  185. tekked: true,
  186. }
  187. ),
  188. }).await.unwrap();
  189. let item1 = entity_gateway.create_item(
  190. item::NewItemEntity {
  191. item: item::ItemDetail::Weapon(
  192. item::weapon::Weapon {
  193. weapon: item::weapon::WeaponType::Handgun,
  194. grind: 0,
  195. special: None,
  196. attrs: [None, None, None],
  197. tekked: true,
  198. }
  199. ),
  200. }).await.unwrap();
  201. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![item0, item1])).await.unwrap();
  202. let mut ship = Box::new(ShipServerState::builder()
  203. .gateway(entity_gateway.clone())
  204. .build());
  205. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  206. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  207. join_lobby(&mut ship, ClientId(1)).await;
  208. join_lobby(&mut ship, ClientId(2)).await;
  209. create_room(&mut ship, ClientId(1), "room", "").await;
  210. join_room(&mut ship, ClientId(2), 0).await;
  211. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  212. client: 0,
  213. target: 0,
  214. unknown: 0,
  215. })))).await.unwrap();
  216. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  217. client: 0,
  218. target: 0,
  219. item_id: 0x10001,
  220. action: 0,
  221. item_amount: 0,
  222. meseta_amount: 0,
  223. unknown: 0,
  224. })))).await.unwrap();
  225. assert!(packets.len() == 2);
  226. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  227. if player_no_longer_has_item.item_id == 0x10001
  228. && player_no_longer_has_item.amount == 0
  229. ));
  230. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  231. assert_eq!(inventory_items.items.len(), 1);
  232. inventory_items.items[0].with_individual(|item| {
  233. assert_eq!(item.id, item::ItemEntityId(1));
  234. }).unwrap();
  235. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  236. assert_eq!(bank_items.items.len(), 1);
  237. bank_items.items[0].with_individual(|item| {
  238. assert_eq!(item.id, item::ItemEntityId(2));
  239. }).unwrap();
  240. }
  241. #[async_std::test]
  242. async fn test_deposit_stacked_item() {
  243. let mut entity_gateway = InMemoryGateway::default();
  244. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  245. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  246. let mut monomates = Vec::new();
  247. for _ in 0..3usize {
  248. monomates.push(entity_gateway.create_item(
  249. item::NewItemEntity {
  250. item: item::ItemDetail::Tool(
  251. item::tool::Tool {
  252. tool: item::tool::ToolType::Monomate,
  253. }
  254. ),
  255. }).await.unwrap());
  256. }
  257. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap();
  258. let mut ship = Box::new(ShipServerState::builder()
  259. .gateway(entity_gateway.clone())
  260. .build());
  261. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  262. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  263. join_lobby(&mut ship, ClientId(1)).await;
  264. join_lobby(&mut ship, ClientId(2)).await;
  265. create_room(&mut ship, ClientId(1), "room", "").await;
  266. join_room(&mut ship, ClientId(2), 0).await;
  267. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  268. client: 0,
  269. target: 0,
  270. unknown: 0,
  271. })))).await.unwrap();
  272. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  273. client: 0,
  274. target: 0,
  275. item_id: 0x10000,
  276. action: 0,
  277. item_amount: 3,
  278. meseta_amount: 0,
  279. unknown: 0,
  280. })))).await.unwrap();
  281. assert!(packets.len() == 2);
  282. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  283. if player_no_longer_has_item.item_id == 0x10000
  284. && player_no_longer_has_item.amount == 3
  285. ));
  286. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  287. assert_eq!(bank_items.items.len(), 1);
  288. bank_items.items[0].with_stacked(|items| {
  289. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  290. vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]);
  291. }).unwrap();
  292. }
  293. #[async_std::test]
  294. async fn test_deposit_partial_stacked_item() {
  295. let mut entity_gateway = InMemoryGateway::default();
  296. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  297. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  298. let mut monomates = Vec::new();
  299. for _ in 0..3usize {
  300. monomates.push(entity_gateway.create_item(
  301. item::NewItemEntity {
  302. item: item::ItemDetail::Tool(
  303. item::tool::Tool {
  304. tool: item::tool::ToolType::Monomate,
  305. }
  306. ),
  307. }).await.unwrap());
  308. }
  309. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap();
  310. let mut ship = Box::new(ShipServerState::builder()
  311. .gateway(entity_gateway.clone())
  312. .build());
  313. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  314. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  315. join_lobby(&mut ship, ClientId(1)).await;
  316. join_lobby(&mut ship, ClientId(2)).await;
  317. create_room(&mut ship, ClientId(1), "room", "").await;
  318. join_room(&mut ship, ClientId(2), 0).await;
  319. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  320. client: 0,
  321. target: 0,
  322. unknown: 0,
  323. })))).await.unwrap();
  324. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  325. client: 0,
  326. target: 0,
  327. item_id: 0x10000,
  328. action: 0,
  329. item_amount: 2,
  330. meseta_amount: 0,
  331. unknown: 0,
  332. })))).await.unwrap();
  333. assert!(packets.len() == 2);
  334. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  335. if player_no_longer_has_item.item_id == 0x10000
  336. && player_no_longer_has_item.amount == 2
  337. ));
  338. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  339. assert_eq!(bank_items.items.len(), 1);
  340. bank_items.items[0].with_stacked(|items| {
  341. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  342. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  343. }).unwrap();
  344. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  345. assert_eq!(inventory_items.items.len(), 1);
  346. inventory_items.items[0].with_stacked(|items| {
  347. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  348. vec![item::ItemEntityId(3)]);
  349. }).unwrap();
  350. }
  351. #[async_std::test]
  352. async fn test_deposit_stacked_item_with_stack_already_in_bank() {
  353. let mut entity_gateway = InMemoryGateway::default();
  354. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  355. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  356. let mut bank_monomates = Vec::new();
  357. let mut inventory_monomates = Vec::new();
  358. for _ in 0..2usize {
  359. inventory_monomates.push(entity_gateway.create_item(
  360. item::NewItemEntity {
  361. item: item::ItemDetail::Tool(
  362. item::tool::Tool {
  363. tool: item::tool::ToolType::Monomate,
  364. }
  365. ),
  366. }).await.unwrap());
  367. bank_monomates.push(entity_gateway.create_item(
  368. item::NewItemEntity {
  369. item: item::ItemDetail::Tool(
  370. item::tool::Tool {
  371. tool: item::tool::ToolType::Monomate,
  372. }
  373. ),
  374. }).await.unwrap());
  375. }
  376. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap();
  377. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), &item::BankIdentifier::Character).await.unwrap();
  378. let mut ship = Box::new(ShipServerState::builder()
  379. .gateway(entity_gateway.clone())
  380. .build());
  381. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  382. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  383. join_lobby(&mut ship, ClientId(1)).await;
  384. join_lobby(&mut ship, ClientId(2)).await;
  385. create_room(&mut ship, ClientId(1), "room", "").await;
  386. join_room(&mut ship, ClientId(2), 0).await;
  387. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  388. client: 0,
  389. target: 0,
  390. unknown: 0,
  391. })))).await.unwrap();
  392. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  393. client: 0,
  394. target: 0,
  395. item_id: 0x10000,
  396. action: 0,
  397. item_amount: 2,
  398. meseta_amount: 0,
  399. unknown: 0,
  400. })))).await.unwrap();
  401. assert!(packets.len() == 2);
  402. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  403. if player_no_longer_has_item.item_id == 0x10000
  404. && player_no_longer_has_item.amount == 2
  405. ));
  406. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  407. assert_eq!(bank_items.items.len(), 1);
  408. bank_items.items[0].with_stacked(|items| {
  409. assert_eq!(items.iter().map(|i| i.id).collect::<BTreeSet<_>>(),
  410. vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)].into_iter().collect::<BTreeSet<_>>() );
  411. }).unwrap();
  412. }
  413. #[async_std::test]
  414. async fn test_deposit_stacked_item_with_full_stack_in_bank() {
  415. let mut entity_gateway = InMemoryGateway::default();
  416. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  417. let mut inventory_monomates = Vec::new();
  418. for _ in 0..2usize {
  419. inventory_monomates.push(entity_gateway.create_item(
  420. item::NewItemEntity {
  421. item: item::ItemDetail::Tool(
  422. item::tool::Tool {
  423. tool: item::tool::ToolType::Monomate,
  424. }
  425. ),
  426. }).await.unwrap());
  427. }
  428. let mut bank_monomates = Vec::new();
  429. for _ in 0..10 {
  430. bank_monomates.push(entity_gateway.create_item(
  431. item::NewItemEntity {
  432. item: item::ItemDetail::Tool(
  433. item::tool::Tool {
  434. tool: item::tool::ToolType::Monomate,
  435. }
  436. ),
  437. }).await.unwrap());
  438. }
  439. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap();
  440. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), &item::BankIdentifier::Character).await.unwrap();
  441. let mut ship = Box::new(ShipServerState::builder()
  442. .gateway(entity_gateway.clone())
  443. .build());
  444. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  445. join_lobby(&mut ship, ClientId(1)).await;
  446. create_room(&mut ship, ClientId(1), "room", "").await;
  447. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  448. client: 0,
  449. target: 0,
  450. unknown: 0,
  451. })))).await.unwrap();
  452. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  453. client: 0,
  454. target: 0,
  455. item_id: 0x10000,
  456. action: 0,
  457. item_amount: 2,
  458. meseta_amount: 0,
  459. unknown: 0,
  460. })))).await;
  461. assert!(packets.is_err());
  462. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  463. assert_eq!(bank_items.items.len(), 1);
  464. bank_items.items[0].with_stacked(|items| {
  465. assert_eq!(items.len(), 10);
  466. }).unwrap();
  467. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  468. assert_eq!(inventory_items.items.len(), 1);
  469. inventory_items.items[0].with_stacked(|items| {
  470. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  471. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  472. }).unwrap();
  473. }
  474. #[async_std::test]
  475. async fn test_deposit_individual_item_in_full_bank() {
  476. let mut entity_gateway = InMemoryGateway::default();
  477. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  478. let mut inventory = Vec::new();
  479. inventory.push(entity_gateway.create_item(
  480. item::NewItemEntity {
  481. item: item::ItemDetail::Weapon(
  482. item::weapon::Weapon {
  483. weapon: item::weapon::WeaponType::Vulcan,
  484. grind: 0,
  485. special: None,
  486. attrs: [None, None, None],
  487. tekked: true,
  488. }
  489. ),
  490. }).await.unwrap());
  491. let mut bank = Vec::new();
  492. for _ in 0..200usize {
  493. bank.push(entity_gateway.create_item(
  494. item::NewItemEntity {
  495. item: item::ItemDetail::Weapon(
  496. item::weapon::Weapon {
  497. weapon: item::weapon::WeaponType::Vulcan,
  498. grind: 0,
  499. special: None,
  500. attrs: [None, None, None],
  501. tekked: true,
  502. }
  503. ),
  504. }).await.unwrap());
  505. }
  506. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap();
  507. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap();
  508. let mut ship = Box::new(ShipServerState::builder()
  509. .gateway(entity_gateway.clone())
  510. .build());
  511. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  512. join_lobby(&mut ship, ClientId(1)).await;
  513. create_room(&mut ship, ClientId(1), "room", "").await;
  514. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  515. client: 0,
  516. target: 0,
  517. unknown: 0,
  518. })))).await.unwrap();
  519. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  520. client: 0,
  521. target: 0,
  522. item_id: 0x10000,
  523. action: 0,
  524. item_amount: 0,
  525. meseta_amount: 0,
  526. unknown: 0,
  527. })))).await;
  528. assert!(packets.is_err());
  529. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  530. assert_eq!(bank_items.items.len(), 200);
  531. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  532. assert_eq!(inventory_items.items.len(), 1);
  533. inventory_items.items[0].with_individual(|item| {
  534. assert_eq!(item.id, item::ItemEntityId(1));
  535. }).unwrap();
  536. }
  537. #[async_std::test]
  538. async fn test_deposit_stacked_item_in_full_bank() {
  539. let mut entity_gateway = InMemoryGateway::default();
  540. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  541. let mut monomates = Vec::new();
  542. for _ in 0..2usize {
  543. monomates.push(entity_gateway.create_item(
  544. item::NewItemEntity {
  545. item: item::ItemDetail::Tool(
  546. item::tool::Tool {
  547. tool: item::tool::ToolType::Monomate,
  548. }
  549. ),
  550. }).await.unwrap());
  551. }
  552. let mut full_bank = Vec::new();
  553. for _ in 0..200usize {
  554. full_bank.push(entity_gateway.create_item(
  555. item::NewItemEntity {
  556. item: item::ItemDetail::Weapon(
  557. item::weapon::Weapon {
  558. weapon: item::weapon::WeaponType::Vulcan,
  559. grind: 0,
  560. special: None,
  561. attrs: [None, None, None],
  562. tekked: true,
  563. }
  564. ),
  565. }).await.unwrap());
  566. }
  567. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap();
  568. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(full_bank), &item::BankIdentifier::Character).await.unwrap();
  569. let mut ship = Box::new(ShipServerState::builder()
  570. .gateway(entity_gateway.clone())
  571. .build());
  572. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  573. join_lobby(&mut ship, ClientId(1)).await;
  574. create_room(&mut ship, ClientId(1), "room", "").await;
  575. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  576. client: 0,
  577. target: 0,
  578. unknown: 0,
  579. })))).await.unwrap();
  580. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  581. client: 0,
  582. target: 0,
  583. item_id: 0x10000,
  584. action: 0,
  585. item_amount: 2,
  586. meseta_amount: 0,
  587. unknown: 0,
  588. })))).await;
  589. assert!(packets.is_err());
  590. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  591. assert_eq!(bank_items.items.len(), 200);
  592. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  593. assert_eq!(inventory_items.items.len(), 1);
  594. inventory_items.items[0].with_stacked(|items| {
  595. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  596. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  597. }).unwrap();
  598. }
  599. #[async_std::test]
  600. async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() {
  601. let mut entity_gateway = InMemoryGateway::default();
  602. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  603. let mut monomates = Vec::new();
  604. for _ in 0..2usize {
  605. monomates.push(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. }).await.unwrap());
  613. }
  614. let mut bank_monomates = Vec::new();
  615. for _ in 0..2usize {
  616. bank_monomates.push(entity_gateway.create_item(
  617. item::NewItemEntity {
  618. item: item::ItemDetail::Tool(
  619. item::tool::Tool {
  620. tool: item::tool::ToolType::Monomate,
  621. }
  622. ),
  623. }).await.unwrap());
  624. }
  625. let mut almost_full_bank: Vec<item::BankItemEntity> = Vec::new();
  626. for _ in 0..199usize {
  627. almost_full_bank.push(entity_gateway.create_item(
  628. item::NewItemEntity {
  629. item: item::ItemDetail::Weapon(
  630. item::weapon::Weapon {
  631. weapon: item::weapon::WeaponType::Vulcan,
  632. grind: 0,
  633. special: None,
  634. attrs: [None, None, None],
  635. tekked: true,
  636. }
  637. ),
  638. }).await.unwrap().into());
  639. }
  640. almost_full_bank.push(bank_monomates.into());
  641. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap();
  642. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(almost_full_bank), &item::BankIdentifier::Character).await.unwrap();
  643. let mut ship = Box::new(ShipServerState::builder()
  644. .gateway(entity_gateway.clone())
  645. .build());
  646. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  647. join_lobby(&mut ship, ClientId(1)).await;
  648. create_room(&mut ship, ClientId(1), "room", "").await;
  649. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  650. client: 0,
  651. target: 0,
  652. unknown: 0,
  653. })))).await.unwrap();
  654. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  655. client: 0,
  656. target: 0,
  657. item_id: 0x10000,
  658. action: 0,
  659. item_amount: 2,
  660. meseta_amount: 0,
  661. unknown: 0,
  662. })))).await.unwrap();
  663. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  664. assert_eq!(bank_items.items.len(), 200);
  665. bank_items.items[199].with_stacked(|items| {
  666. assert_eq!(items.len(), 4);
  667. }).unwrap();
  668. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  669. assert_eq!(inventory_items.items.len(), 0);
  670. }
  671. #[async_std::test]
  672. async fn test_deposit_meseta() {
  673. let mut entity_gateway = InMemoryGateway::default();
  674. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  675. entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap();
  676. let mut ship = Box::new(ShipServerState::builder()
  677. .gateway(entity_gateway.clone())
  678. .build());
  679. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  680. join_lobby(&mut ship, ClientId(1)).await;
  681. create_room(&mut ship, ClientId(1), "room", "").await;
  682. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  683. client: 0,
  684. target: 0,
  685. unknown: 0,
  686. })))).await.unwrap();
  687. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  688. client: 0,
  689. target: 0,
  690. item_id: 0xFFFFFFFF,
  691. action: 0,
  692. item_amount: 0,
  693. meseta_amount: 23,
  694. unknown: 0,
  695. })))).await.unwrap();
  696. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  697. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  698. assert!(c1_meseta.0 == 277);
  699. assert!(c1_bank_meseta.0 == 23);
  700. }
  701. #[async_std::test]
  702. async fn test_deposit_too_much_meseta() {
  703. let mut entity_gateway = InMemoryGateway::default();
  704. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  705. entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap();
  706. entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(999980)).await.unwrap();
  707. let mut ship = Box::new(ShipServerState::builder()
  708. .gateway(entity_gateway.clone())
  709. .build());
  710. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  711. join_lobby(&mut ship, ClientId(1)).await;
  712. create_room(&mut ship, ClientId(1), "room", "").await;
  713. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  714. client: 0,
  715. target: 0,
  716. unknown: 0,
  717. })))).await.unwrap();
  718. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  719. client: 0,
  720. target: 0,
  721. item_id: 0xFFFFFFFF,
  722. action: 0,
  723. item_amount: 0,
  724. meseta_amount: 23,
  725. unknown: 0,
  726. })))).await;
  727. assert!(packets.is_err());
  728. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  729. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  730. assert!(c1_meseta.0 == 300);
  731. assert!(c1_bank_meseta.0 == 999980);
  732. }
  733. #[async_std::test]
  734. async fn test_deposit_meseta_when_bank_is_maxed() {
  735. let mut entity_gateway = InMemoryGateway::default();
  736. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  737. entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap();
  738. entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(999999)).await.unwrap();
  739. let mut ship = Box::new(ShipServerState::builder()
  740. .gateway(entity_gateway.clone())
  741. .build());
  742. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  743. join_lobby(&mut ship, ClientId(1)).await;
  744. create_room(&mut ship, ClientId(1), "room", "").await;
  745. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  746. client: 0,
  747. target: 0,
  748. unknown: 0,
  749. })))).await.unwrap();
  750. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  751. client: 0,
  752. target: 0,
  753. item_id: 0xFFFFFFFF,
  754. action: 0,
  755. item_amount: 0,
  756. meseta_amount: 23,
  757. unknown: 0,
  758. })))).await;
  759. assert!(packets.is_err());
  760. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  761. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  762. assert!(c1_meseta.0 == 300);
  763. assert!(c1_bank_meseta.0 == 999999);
  764. }
  765. #[async_std::test]
  766. async fn test_withdraw_individual_item() {
  767. let mut entity_gateway = InMemoryGateway::default();
  768. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  769. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  770. let mut bank = Vec::new();
  771. bank.push(entity_gateway.create_item(
  772. item::NewItemEntity {
  773. item: item::ItemDetail::Weapon(
  774. item::weapon::Weapon {
  775. weapon: item::weapon::WeaponType::Saber,
  776. grind: 0,
  777. special: None,
  778. attrs: [None, None, None],
  779. tekked: true,
  780. }
  781. ),
  782. }).await.unwrap());
  783. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap();
  784. let mut ship = Box::new(ShipServerState::builder()
  785. .gateway(entity_gateway.clone())
  786. .build());
  787. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  788. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  789. join_lobby(&mut ship, ClientId(1)).await;
  790. join_lobby(&mut ship, ClientId(2)).await;
  791. create_room(&mut ship, ClientId(1), "room", "").await;
  792. join_room(&mut ship, ClientId(2), 0).await;
  793. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  794. client: 0,
  795. target: 0,
  796. unknown: 0,
  797. })))).await.unwrap();
  798. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  799. client: 0,
  800. target: 0,
  801. item_id: 0x20000,
  802. action: 1,
  803. item_amount: 0,
  804. meseta_amount: 0,
  805. unknown: 0,
  806. })))).await.unwrap();
  807. assert!(packets.len() == 2);
  808. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  809. if create_item.item_id == 0x20000
  810. ));
  811. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  812. assert_eq!(inventory_items.items.len(), 1);
  813. inventory_items.items[0].with_individual(|item| {
  814. assert_eq!(item.id, item::ItemEntityId(1));
  815. }).unwrap();
  816. }
  817. #[async_std::test]
  818. async fn test_withdraw_stacked_item() {
  819. let mut entity_gateway = InMemoryGateway::default();
  820. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  821. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  822. let mut monomates = Vec::new();
  823. for _ in 0..3usize {
  824. monomates.push(entity_gateway.create_item(
  825. item::NewItemEntity {
  826. item: item::ItemDetail::Tool(
  827. item::tool::Tool {
  828. tool: item::tool::ToolType::Monomate,
  829. }
  830. ),
  831. }).await.unwrap());
  832. }
  833. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap();
  834. let mut ship = Box::new(ShipServerState::builder()
  835. .gateway(entity_gateway.clone())
  836. .build());
  837. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  838. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  839. join_lobby(&mut ship, ClientId(1)).await;
  840. join_lobby(&mut ship, ClientId(2)).await;
  841. create_room(&mut ship, ClientId(1), "room", "").await;
  842. join_room(&mut ship, ClientId(2), 0).await;
  843. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  844. client: 0,
  845. target: 0,
  846. unknown: 0,
  847. })))).await.unwrap();
  848. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  849. client: 0,
  850. target: 0,
  851. item_id: 0x20000,
  852. action: 1,
  853. item_amount: 3,
  854. meseta_amount: 0,
  855. unknown: 0,
  856. })))).await.unwrap();
  857. assert!(packets.len() == 2);
  858. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  859. if create_item.item_id == 0x20000
  860. ));
  861. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  862. assert_eq!(inventory_items.items.len(), 1);
  863. inventory_items.items[0].with_stacked(|items| {
  864. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  865. vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]);
  866. }).unwrap();
  867. }
  868. #[async_std::test]
  869. async fn test_withdraw_partial_stacked_item() {
  870. let mut entity_gateway = InMemoryGateway::default();
  871. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  872. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  873. let mut monomates = Vec::new();
  874. for _ in 0..3usize {
  875. monomates.push(entity_gateway.create_item(
  876. item::NewItemEntity {
  877. item: item::ItemDetail::Tool(
  878. item::tool::Tool {
  879. tool: item::tool::ToolType::Monomate,
  880. }
  881. ),
  882. }).await.unwrap());
  883. }
  884. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap();
  885. let mut ship = Box::new(ShipServerState::builder()
  886. .gateway(entity_gateway.clone())
  887. .build());
  888. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  889. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  890. join_lobby(&mut ship, ClientId(1)).await;
  891. join_lobby(&mut ship, ClientId(2)).await;
  892. create_room(&mut ship, ClientId(1), "room", "").await;
  893. join_room(&mut ship, ClientId(2), 0).await;
  894. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  895. client: 0,
  896. target: 0,
  897. unknown: 0,
  898. })))).await.unwrap();
  899. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  900. client: 0,
  901. target: 0,
  902. item_id: 0x20000,
  903. action: 1,
  904. item_amount: 2,
  905. meseta_amount: 0,
  906. unknown: 0,
  907. })))).await.unwrap();
  908. assert!(packets.len() == 2);
  909. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  910. if create_item.item_id == 0x20001
  911. ));
  912. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  913. assert_eq!(bank_items.items.len(), 1);
  914. bank_items.items[0].with_stacked(|items| {
  915. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  916. vec![item::ItemEntityId(3)]);
  917. }).unwrap();
  918. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  919. assert_eq!(inventory_items.items.len(), 1);
  920. inventory_items.items[0].with_stacked(|items| {
  921. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  922. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  923. }).unwrap();
  924. }
  925. #[async_std::test]
  926. async fn test_withdraw_stacked_item_with_stack_already_in_inventory() {
  927. let mut entity_gateway = InMemoryGateway::default();
  928. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  929. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  930. let mut inventory_monomates = Vec::new();
  931. let mut bank_monomates = Vec::new();
  932. for _ in 0..2usize {
  933. inventory_monomates.push(entity_gateway.create_item(
  934. item::NewItemEntity {
  935. item: item::ItemDetail::Tool(
  936. item::tool::Tool {
  937. tool: item::tool::ToolType::Monomate,
  938. }
  939. ),
  940. }).await.unwrap());
  941. bank_monomates.push(entity_gateway.create_item(
  942. item::NewItemEntity {
  943. item: item::ItemDetail::Tool(
  944. item::tool::Tool {
  945. tool: item::tool::ToolType::Monomate,
  946. }
  947. ),
  948. }).await.unwrap());
  949. }
  950. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap();
  951. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), &item::BankIdentifier::Character).await.unwrap();
  952. let mut ship = Box::new(ShipServerState::builder()
  953. .gateway(entity_gateway.clone())
  954. .build());
  955. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  956. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  957. join_lobby(&mut ship, ClientId(1)).await;
  958. join_lobby(&mut ship, ClientId(2)).await;
  959. create_room(&mut ship, ClientId(1), "room", "").await;
  960. join_room(&mut ship, ClientId(2), 0).await;
  961. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  962. client: 0,
  963. target: 0,
  964. unknown: 0,
  965. })))).await.unwrap();
  966. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  967. client: 0,
  968. target: 0,
  969. item_id: 0x20000,
  970. action: 1,
  971. item_amount: 2,
  972. meseta_amount: 0,
  973. unknown: 0,
  974. })))).await.unwrap();
  975. assert!(packets.len() == 2);
  976. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  977. if create_item.item_id == 0x20000
  978. ));
  979. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  980. assert_eq!(bank_items.items.len(), 0);
  981. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  982. assert_eq!(inventory_items.items.len(), 1);
  983. inventory_items.items[0].with_stacked(|items| {
  984. assert_eq!(items.iter().map(|i| i.id).collect::<BTreeSet<_>>(),
  985. vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)].into_iter().collect::<BTreeSet<_>>());
  986. }).unwrap();
  987. }
  988. #[async_std::test]
  989. async fn test_withdraw_stacked_item_with_full_stack_in_inventory() {
  990. let mut entity_gateway = InMemoryGateway::default();
  991. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  992. let mut bank_monomates = Vec::new();
  993. for _ in 0..2usize {
  994. bank_monomates.push(entity_gateway.create_item(
  995. item::NewItemEntity {
  996. item: item::ItemDetail::Tool(
  997. item::tool::Tool {
  998. tool: item::tool::ToolType::Monomate,
  999. }
  1000. ),
  1001. }).await.unwrap());
  1002. }
  1003. let mut inventory_monomates = Vec::new();
  1004. for _ in 0..10usize {
  1005. inventory_monomates.push(entity_gateway.create_item(
  1006. item::NewItemEntity {
  1007. item: item::ItemDetail::Tool(
  1008. item::tool::Tool {
  1009. tool: item::tool::ToolType::Monomate,
  1010. }
  1011. ),
  1012. }).await.unwrap());
  1013. }
  1014. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap();
  1015. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), &item::BankIdentifier::Character).await.unwrap();
  1016. let mut ship = Box::new(ShipServerState::builder()
  1017. .gateway(entity_gateway.clone())
  1018. .build());
  1019. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1020. join_lobby(&mut ship, ClientId(1)).await;
  1021. create_room(&mut ship, ClientId(1), "room", "").await;
  1022. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1023. client: 0,
  1024. target: 0,
  1025. unknown: 0,
  1026. })))).await.unwrap();
  1027. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1028. client: 0,
  1029. target: 0,
  1030. item_id: 0x20000,
  1031. action: 1,
  1032. item_amount: 2,
  1033. meseta_amount: 0,
  1034. unknown: 0,
  1035. })))).await;
  1036. assert!(packets.is_err());
  1037. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  1038. assert_eq!(bank_items.items.len(), 1);
  1039. bank_items.items[0].with_stacked(|items| {
  1040. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  1041. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  1042. }).unwrap();
  1043. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1044. assert_eq!(inventory_items.items.len(), 1);
  1045. inventory_items.items[0].with_stacked(|items| {
  1046. assert_eq!(items.len(), 10);
  1047. }).unwrap();
  1048. }
  1049. #[async_std::test]
  1050. async fn test_withdraw_individual_item_in_full_inventory() {
  1051. let mut entity_gateway = InMemoryGateway::default();
  1052. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  1053. let mut bank = Vec::new();
  1054. bank.push(entity_gateway.create_item(
  1055. item::NewItemEntity {
  1056. item: item::ItemDetail::Weapon(
  1057. item::weapon::Weapon {
  1058. weapon: item::weapon::WeaponType::Vulcan,
  1059. grind: 0,
  1060. special: None,
  1061. attrs: [None, None, None],
  1062. tekked: true,
  1063. }
  1064. ),
  1065. }).await.unwrap());
  1066. let mut inventory = Vec::new();
  1067. for _ in 0..30usize {
  1068. inventory.push(entity_gateway.create_item(
  1069. item::NewItemEntity {
  1070. item: item::ItemDetail::Weapon(
  1071. item::weapon::Weapon {
  1072. weapon: item::weapon::WeaponType::Vulcan,
  1073. grind: 0,
  1074. special: None,
  1075. attrs: [None, None, None],
  1076. tekked: true,
  1077. }
  1078. ),
  1079. }).await.unwrap());
  1080. }
  1081. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap();
  1082. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), &item::BankIdentifier::Character).await.unwrap();
  1083. let mut ship = Box::new(ShipServerState::builder()
  1084. .gateway(entity_gateway.clone())
  1085. .build());
  1086. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1087. join_lobby(&mut ship, ClientId(1)).await;
  1088. create_room(&mut ship, ClientId(1), "room", "").await;
  1089. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1090. client: 0,
  1091. target: 0,
  1092. unknown: 0,
  1093. })))).await.unwrap();
  1094. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1095. client: 0,
  1096. target: 0,
  1097. item_id: 0x20000,
  1098. action: 1,
  1099. item_amount: 0,
  1100. meseta_amount: 0,
  1101. unknown: 0,
  1102. })))).await;
  1103. assert!(packets.is_err());
  1104. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  1105. assert_eq!(bank_items.items.len(), 1);
  1106. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1107. assert_eq!(inventory_items.items.len(), 30);
  1108. }
  1109. #[async_std::test]
  1110. async fn test_withdraw_stacked_item_in_full_inventory() {
  1111. let mut entity_gateway = InMemoryGateway::default();
  1112. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  1113. let mut monomates = Vec::new();
  1114. for _ in 0..2usize {
  1115. monomates.push(entity_gateway.create_item(
  1116. item::NewItemEntity {
  1117. item: item::ItemDetail::Tool(
  1118. item::tool::Tool {
  1119. tool: item::tool::ToolType::Monomate,
  1120. }
  1121. ),
  1122. }).await.unwrap());
  1123. }
  1124. let mut inventory = Vec::new();
  1125. for _ in 0..30usize {
  1126. inventory.push(entity_gateway.create_item(
  1127. item::NewItemEntity {
  1128. item: item::ItemDetail::Weapon(
  1129. item::weapon::Weapon {
  1130. weapon: item::weapon::WeaponType::Vulcan,
  1131. grind: 0,
  1132. special: None,
  1133. attrs: [None, None, None],
  1134. tekked: true,
  1135. }
  1136. ),
  1137. }).await.unwrap());
  1138. }
  1139. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap();
  1140. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap();
  1141. let mut ship = Box::new(ShipServerState::builder()
  1142. .gateway(entity_gateway.clone())
  1143. .build());
  1144. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1145. join_lobby(&mut ship, ClientId(1)).await;
  1146. create_room(&mut ship, ClientId(1), "room", "").await;
  1147. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1148. client: 0,
  1149. target: 0,
  1150. unknown: 0,
  1151. })))).await.unwrap();
  1152. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1153. client: 0,
  1154. target: 0,
  1155. item_id: 0x20000,
  1156. action: 1,
  1157. item_amount: 2,
  1158. meseta_amount: 0,
  1159. unknown: 0,
  1160. })))).await;
  1161. assert!(packets.is_err());
  1162. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  1163. assert_eq!(bank_items.items.len(), 1);
  1164. bank_items.items[0].with_stacked(|items| {
  1165. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  1166. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  1167. }).unwrap();
  1168. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1169. assert_eq!(inventory_items.items.len(), 30);
  1170. }
  1171. #[async_std::test]
  1172. async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() {
  1173. let mut entity_gateway = InMemoryGateway::default();
  1174. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  1175. let mut bank_item = Vec::new();
  1176. for _ in 0..2usize {
  1177. bank_item.push(entity_gateway.create_item(
  1178. item::NewItemEntity {
  1179. item: item::ItemDetail::Tool(
  1180. item::tool::Tool {
  1181. tool: item::tool::ToolType::Monomate,
  1182. }
  1183. ),
  1184. }).await.unwrap());
  1185. }
  1186. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_item]), &item::BankIdentifier::Character).await.unwrap();
  1187. let mut items = Vec::new();
  1188. for _i in 0..29usize {
  1189. items.push(entity_gateway.create_item(
  1190. item::NewItemEntity {
  1191. item: item::ItemDetail::Weapon(
  1192. item::weapon::Weapon {
  1193. weapon: item::weapon::WeaponType::Vulcan,
  1194. grind: 0,
  1195. special: None,
  1196. attrs: [None, None, None],
  1197. tekked: true,
  1198. }
  1199. ),
  1200. }).await.unwrap().into());
  1201. }
  1202. let mut item29 = Vec::new();
  1203. for _ in 0..2usize {
  1204. item29.push(entity_gateway.create_item(
  1205. item::NewItemEntity {
  1206. item: item::ItemDetail::Tool(
  1207. item::tool::Tool {
  1208. tool: item::tool::ToolType::Monomate,
  1209. }
  1210. ),
  1211. }).await.unwrap());
  1212. }
  1213. items.push(item::InventoryItemEntity::Stacked(item29));
  1214. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(items)).await.unwrap();
  1215. let mut ship = Box::new(ShipServerState::builder()
  1216. .gateway(entity_gateway.clone())
  1217. .build());
  1218. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1219. join_lobby(&mut ship, ClientId(1)).await;
  1220. create_room(&mut ship, ClientId(1), "room", "").await;
  1221. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1222. client: 0,
  1223. target: 0,
  1224. unknown: 0,
  1225. })))).await.unwrap();
  1226. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1227. client: 0,
  1228. target: 0,
  1229. item_id: 0x20000,
  1230. action: 1,
  1231. item_amount: 2,
  1232. meseta_amount: 0,
  1233. unknown: 0,
  1234. })))).await.unwrap();
  1235. let bank_items = entity_gateway.get_character_bank(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  1236. assert!(bank_items.items.len() == 0);
  1237. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1238. assert!(inventory_items.items.len() == 30);
  1239. match &inventory_items.items[29] {
  1240. item::InventoryItemEntity::Stacked(items) => {
  1241. assert_eq!(items.len(), 4);
  1242. },
  1243. _ => panic!(),
  1244. }
  1245. }
  1246. #[async_std::test]
  1247. async fn test_withdraw_meseta() {
  1248. let mut entity_gateway = InMemoryGateway::default();
  1249. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  1250. entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap();
  1251. let mut ship = Box::new(ShipServerState::builder()
  1252. .gateway(entity_gateway.clone())
  1253. .build());
  1254. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1255. join_lobby(&mut ship, ClientId(1)).await;
  1256. create_room(&mut ship, ClientId(1), "room", "").await;
  1257. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1258. client: 0,
  1259. target: 0,
  1260. unknown: 0,
  1261. })))).await.unwrap();
  1262. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1263. client: 0,
  1264. target: 0,
  1265. item_id: 0xFFFFFFFF,
  1266. action: 1,
  1267. item_amount: 0,
  1268. meseta_amount: 23,
  1269. unknown: 0,
  1270. })))).await.unwrap();
  1271. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  1272. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  1273. assert!(c1_meseta.0 == 23);
  1274. assert!(c1_bank_meseta.0 == 277);
  1275. }
  1276. #[async_std::test]
  1277. async fn test_withdraw_too_much_meseta() {
  1278. let mut entity_gateway = InMemoryGateway::default();
  1279. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  1280. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999980)).await.unwrap();
  1281. entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap();
  1282. let mut ship = Box::new(ShipServerState::builder()
  1283. .gateway(entity_gateway.clone())
  1284. .build());
  1285. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1286. join_lobby(&mut ship, ClientId(1)).await;
  1287. create_room(&mut ship, ClientId(1), "room", "").await;
  1288. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1289. client: 0,
  1290. target: 0,
  1291. unknown: 0,
  1292. })))).await.unwrap();
  1293. let packet = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1294. client: 0,
  1295. target: 0,
  1296. item_id: 0xFFFFFFFF,
  1297. action: 1,
  1298. item_amount: 0,
  1299. meseta_amount: 23,
  1300. unknown: 0,
  1301. })))).await;
  1302. assert!(packet.is_err());
  1303. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  1304. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  1305. assert!(c1_meseta.0 == 999980);
  1306. assert!(c1_bank_meseta.0 == 300);
  1307. }
  1308. #[async_std::test]
  1309. async fn test_withdraw_meseta_inventory_is_maxed() {
  1310. let mut entity_gateway = InMemoryGateway::default();
  1311. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  1312. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  1313. entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap();
  1314. let mut ship = Box::new(ShipServerState::builder()
  1315. .gateway(entity_gateway.clone())
  1316. .build());
  1317. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1318. join_lobby(&mut ship, ClientId(1)).await;
  1319. create_room(&mut ship, ClientId(1), "room", "").await;
  1320. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1321. client: 0,
  1322. target: 0,
  1323. unknown: 0,
  1324. })))).await.unwrap();
  1325. let packet = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1326. client: 0,
  1327. target: 0,
  1328. item_id: 0xFFFFFFFF,
  1329. action: 1,
  1330. item_amount: 0,
  1331. meseta_amount: 23,
  1332. unknown: 0,
  1333. })))).await;
  1334. assert!(packet.is_err());
  1335. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  1336. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  1337. assert!(c1_meseta.0 == 999999);
  1338. assert!(c1_bank_meseta.0 == 300);
  1339. }
  1340. #[async_std::test]
  1341. async fn test_withdraw_meseta_and_buy_a_few_monomates_with_it() {
  1342. let mut entity_gateway = InMemoryGateway::default();
  1343. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  1344. entity_gateway.set_character_meseta(&char1.id, item::Meseta(100)).await.unwrap();
  1345. entity_gateway.set_bank_meseta(&char1.id, &item::BankIdentifier::Character, item::Meseta(300)).await.unwrap();
  1346. let mut ship = Box::new(ShipServerState::builder()
  1347. .gateway(entity_gateway.clone())
  1348. .build());
  1349. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1350. join_lobby(&mut ship, ClientId(1)).await;
  1351. create_room(&mut ship, ClientId(1), "room", "").await;
  1352. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1353. client: 0,
  1354. target: 0,
  1355. unknown: 0,
  1356. })))).await.unwrap();
  1357. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1358. client: 0,
  1359. target: 0,
  1360. item_id: 0xFFFFFFFF,
  1361. action: 1,
  1362. item_amount: 0,
  1363. meseta_amount: 60,
  1364. unknown: 0,
  1365. })))).await.unwrap();
  1366. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  1367. client: 255,
  1368. target: 255,
  1369. shop_type: 0,
  1370. })))).await.unwrap();
  1371. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  1372. client: 255,
  1373. target: 255,
  1374. item_id: 0x10000,
  1375. shop_type: 0,
  1376. shop_index: 0,
  1377. amount: 3,
  1378. unknown1: 0,
  1379. })))).await.unwrap();
  1380. //let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  1381. //let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, &item::BankIdentifier::Character).await.unwrap();
  1382. //assert!(c1_meseta.0 == 23);
  1383. //assert!(c1_bank_meseta.0 == 277);
  1384. }