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.

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