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.

1574 lines
59 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
  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").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. }
  26. ),
  27. }).await.unwrap();
  28. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![item]), item::BankName("".into())).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().collect::<Vec<_>>();
  37. assert!(matches!(&packets[0], (_, SendShipPacket::FullCharacter(fc)) if fc.character.bank.items[0].data1[0..3] == [0x00, 0x08, 0x04] ));
  38. }
  39. #[async_std::test]
  40. async fn test_request_bank_items() {
  41. let mut entity_gateway = InMemoryGateway::default();
  42. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  43. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  44. 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::BankName("".into())).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().collect::<Vec<_>>();
  71. assert!(matches!(&packets[0], (_, SendShipPacket::BankItemList (bank_item_list))
  72. if bank_item_list.item_count == 3
  73. && bank_item_list.size == 0x18 * 3 + 0x14
  74. && bank_item_list.items[0].data1[0..3] == [0x00, 0x08, 0x04]
  75. && bank_item_list.items[1].data1[0..3] == [0x00, 0x08, 0x04]
  76. && bank_item_list.items[2].data1[0..3] == [0x00, 0x08, 0x04]
  77. ));
  78. }
  79. #[async_std::test]
  80. async fn test_request_stacked_bank_items() {
  81. let mut entity_gateway = InMemoryGateway::default();
  82. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  83. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  84. 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::BankName("".into())).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().collect::<Vec<_>>();
  107. assert!(matches!(&packets[0], (_, SendShipPacket::BankItemList (bank_item_list))
  108. if bank_item_list.item_count == 1
  109. && bank_item_list.size == 0x18 + 0x14
  110. && bank_item_list.items[0].data1[0..3] == [0x03, 0x00, 0x00]
  111. && bank_item_list.items[0].amount == 3
  112. ));
  113. }
  114. #[async_std::test]
  115. async fn test_request_bank_items_sorted() {
  116. let mut entity_gateway = InMemoryGateway::default();
  117. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  118. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  119. 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::BankName("".into())).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().collect::<Vec<_>>();
  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").await;
  176. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").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().for_each(drop);
  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().collect::<Vec<_>>();
  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 bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  231. assert_eq!(bank_items.items.len(), 1);
  232. bank_items.items[0].with_individual(|item| {
  233. assert_eq!(item.id, item::ItemEntityId(2));
  234. }).unwrap();
  235. }
  236. #[async_std::test]
  237. async fn test_deposit_stacked_item() {
  238. let mut entity_gateway = InMemoryGateway::default();
  239. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  240. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  241. let mut monomates = Vec::new();
  242. for _ in 0..3usize {
  243. monomates.push(entity_gateway.create_item(
  244. item::NewItemEntity {
  245. item: item::ItemDetail::Tool(
  246. item::tool::Tool {
  247. tool: item::tool::ToolType::Monomate,
  248. }
  249. ),
  250. }).await.unwrap());
  251. }
  252. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap();
  253. let mut ship = Box::new(ShipServerState::builder()
  254. .gateway(entity_gateway.clone())
  255. .build());
  256. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  257. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  258. join_lobby(&mut ship, ClientId(1)).await;
  259. join_lobby(&mut ship, ClientId(2)).await;
  260. create_room(&mut ship, ClientId(1), "room", "").await;
  261. join_room(&mut ship, ClientId(2), 0).await;
  262. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  263. client: 0,
  264. target: 0,
  265. unknown: 0,
  266. })))).await.unwrap().for_each(drop);
  267. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  268. client: 0,
  269. target: 0,
  270. item_id: 0x10000,
  271. action: 0,
  272. item_amount: 3,
  273. meseta_amount: 0,
  274. unknown: 0,
  275. })))).await.unwrap().collect::<Vec<_>>();
  276. assert!(packets.len() == 2);
  277. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  278. if player_no_longer_has_item.item_id == 0x10000
  279. && player_no_longer_has_item.amount == 3
  280. ));
  281. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  282. assert_eq!(bank_items.items.len(), 1);
  283. bank_items.items[0].with_stacked(|items| {
  284. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  285. vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]);
  286. }).unwrap();
  287. }
  288. #[async_std::test]
  289. async fn test_deposit_partial_stacked_item() {
  290. let mut entity_gateway = InMemoryGateway::default();
  291. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  292. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  293. let mut monomates = Vec::new();
  294. for _ in 0..3usize {
  295. monomates.push(entity_gateway.create_item(
  296. item::NewItemEntity {
  297. item: item::ItemDetail::Tool(
  298. item::tool::Tool {
  299. tool: item::tool::ToolType::Monomate,
  300. }
  301. ),
  302. }).await.unwrap());
  303. }
  304. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap();
  305. let mut ship = Box::new(ShipServerState::builder()
  306. .gateway(entity_gateway.clone())
  307. .build());
  308. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  309. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  310. join_lobby(&mut ship, ClientId(1)).await;
  311. join_lobby(&mut ship, ClientId(2)).await;
  312. create_room(&mut ship, ClientId(1), "room", "").await;
  313. join_room(&mut ship, ClientId(2), 0).await;
  314. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  315. client: 0,
  316. target: 0,
  317. unknown: 0,
  318. })))).await.unwrap().for_each(drop);
  319. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  320. client: 0,
  321. target: 0,
  322. item_id: 0x10000,
  323. action: 0,
  324. item_amount: 2,
  325. meseta_amount: 0,
  326. unknown: 0,
  327. })))).await.unwrap().collect::<Vec<_>>();
  328. assert!(packets.len() == 2);
  329. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  330. if player_no_longer_has_item.item_id == 0x10000
  331. && player_no_longer_has_item.amount == 2
  332. ));
  333. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  334. assert_eq!(bank_items.items.len(), 1);
  335. bank_items.items[0].with_stacked(|items| {
  336. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  337. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  338. }).unwrap();
  339. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  340. assert_eq!(inventory_items.items.len(), 1);
  341. inventory_items.items[0].with_stacked(|items| {
  342. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  343. vec![item::ItemEntityId(3)]);
  344. }).unwrap();
  345. }
  346. #[async_std::test]
  347. async fn test_deposit_stacked_item_with_stack_already_in_bank() {
  348. let mut entity_gateway = InMemoryGateway::default();
  349. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  350. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  351. let mut bank_monomates = Vec::new();
  352. let mut inventory_monomates = Vec::new();
  353. for _ in 0..2usize {
  354. inventory_monomates.push(entity_gateway.create_item(
  355. item::NewItemEntity {
  356. item: item::ItemDetail::Tool(
  357. item::tool::Tool {
  358. tool: item::tool::ToolType::Monomate,
  359. }
  360. ),
  361. }).await.unwrap());
  362. bank_monomates.push(entity_gateway.create_item(
  363. item::NewItemEntity {
  364. item: item::ItemDetail::Tool(
  365. item::tool::Tool {
  366. tool: item::tool::ToolType::Monomate,
  367. }
  368. ),
  369. }).await.unwrap());
  370. }
  371. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap();
  372. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), item::BankName("".into())).await.unwrap();
  373. let mut ship = Box::new(ShipServerState::builder()
  374. .gateway(entity_gateway.clone())
  375. .build());
  376. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  377. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  378. join_lobby(&mut ship, ClientId(1)).await;
  379. join_lobby(&mut ship, ClientId(2)).await;
  380. create_room(&mut ship, ClientId(1), "room", "").await;
  381. join_room(&mut ship, ClientId(2), 0).await;
  382. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  383. client: 0,
  384. target: 0,
  385. unknown: 0,
  386. })))).await.unwrap().for_each(drop);
  387. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  388. client: 0,
  389. target: 0,
  390. item_id: 0x10000,
  391. action: 0,
  392. item_amount: 2,
  393. meseta_amount: 0,
  394. unknown: 0,
  395. })))).await.unwrap().collect::<Vec<_>>();
  396. assert!(packets.len() == 2);
  397. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)}))
  398. if player_no_longer_has_item.item_id == 0x10000
  399. && player_no_longer_has_item.amount == 2
  400. ));
  401. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  402. assert_eq!(bank_items.items.len(), 1);
  403. bank_items.items[0].with_stacked(|items| {
  404. assert_eq!(items.iter().map(|i| i.id).collect::<BTreeSet<_>>(),
  405. vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)].into_iter().collect::<BTreeSet<_>>() );
  406. }).unwrap();
  407. }
  408. #[async_std::test]
  409. async fn test_deposit_stacked_item_with_full_stack_in_bank() {
  410. let mut entity_gateway = InMemoryGateway::default();
  411. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  412. let mut inventory_monomates = Vec::new();
  413. for _ in 0..2usize {
  414. inventory_monomates.push(entity_gateway.create_item(
  415. item::NewItemEntity {
  416. item: item::ItemDetail::Tool(
  417. item::tool::Tool {
  418. tool: item::tool::ToolType::Monomate,
  419. }
  420. ),
  421. }).await.unwrap());
  422. }
  423. let mut bank_monomates = Vec::new();
  424. for _ in 0..10 {
  425. bank_monomates.push(entity_gateway.create_item(
  426. item::NewItemEntity {
  427. item: item::ItemDetail::Tool(
  428. item::tool::Tool {
  429. tool: item::tool::ToolType::Monomate,
  430. }
  431. ),
  432. }).await.unwrap());
  433. }
  434. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap();
  435. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), item::BankName("".into())).await.unwrap();
  436. let mut ship = Box::new(ShipServerState::builder()
  437. .gateway(entity_gateway.clone())
  438. .build());
  439. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  440. join_lobby(&mut ship, ClientId(1)).await;
  441. create_room(&mut ship, ClientId(1), "room", "").await;
  442. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  443. client: 0,
  444. target: 0,
  445. unknown: 0,
  446. })))).await.unwrap().for_each(drop);
  447. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  448. client: 0,
  449. target: 0,
  450. item_id: 0x10000,
  451. action: 0,
  452. item_amount: 2,
  453. meseta_amount: 0,
  454. unknown: 0,
  455. })))).await;
  456. assert!(packets.is_err());
  457. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  458. assert_eq!(bank_items.items.len(), 1);
  459. bank_items.items[0].with_stacked(|items| {
  460. assert_eq!(items.len(), 10);
  461. }).unwrap();
  462. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  463. assert_eq!(inventory_items.items.len(), 1);
  464. inventory_items.items[0].with_stacked(|items| {
  465. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  466. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  467. }).unwrap();
  468. }
  469. #[async_std::test]
  470. async fn test_deposit_individual_item_in_full_bank() {
  471. let mut entity_gateway = InMemoryGateway::default();
  472. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  473. let mut inventory = Vec::new();
  474. inventory.push(entity_gateway.create_item(
  475. item::NewItemEntity {
  476. item: item::ItemDetail::Weapon(
  477. item::weapon::Weapon {
  478. weapon: item::weapon::WeaponType::Vulcan,
  479. grind: 0,
  480. special: None,
  481. attrs: [None, None, None],
  482. tekked: true,
  483. }
  484. ),
  485. }).await.unwrap());
  486. let mut bank = Vec::new();
  487. for _ in 0..200usize {
  488. bank.push(entity_gateway.create_item(
  489. item::NewItemEntity {
  490. item: item::ItemDetail::Weapon(
  491. item::weapon::Weapon {
  492. weapon: item::weapon::WeaponType::Vulcan,
  493. grind: 0,
  494. special: None,
  495. attrs: [None, None, None],
  496. tekked: true,
  497. }
  498. ),
  499. }).await.unwrap());
  500. }
  501. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap();
  502. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), item::BankName("".into())).await.unwrap();
  503. let mut ship = Box::new(ShipServerState::builder()
  504. .gateway(entity_gateway.clone())
  505. .build());
  506. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  507. join_lobby(&mut ship, ClientId(1)).await;
  508. create_room(&mut ship, ClientId(1), "room", "").await;
  509. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  510. client: 0,
  511. target: 0,
  512. unknown: 0,
  513. })))).await.unwrap().for_each(drop);
  514. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  515. client: 0,
  516. target: 0,
  517. item_id: 0x10000,
  518. action: 0,
  519. item_amount: 0,
  520. meseta_amount: 0,
  521. unknown: 0,
  522. })))).await;
  523. assert!(packets.is_err());
  524. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  525. assert_eq!(bank_items.items.len(), 200);
  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_individual(|item| {
  529. assert_eq!(item.id, item::ItemEntityId(1));
  530. }).unwrap();
  531. }
  532. #[async_std::test]
  533. async fn test_deposit_stacked_item_in_full_bank() {
  534. let mut entity_gateway = InMemoryGateway::default();
  535. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  536. let mut monomates = Vec::new();
  537. for _ in 0..2usize {
  538. monomates.push(entity_gateway.create_item(
  539. item::NewItemEntity {
  540. item: item::ItemDetail::Tool(
  541. item::tool::Tool {
  542. tool: item::tool::ToolType::Monomate,
  543. }
  544. ),
  545. }).await.unwrap());
  546. }
  547. let mut full_bank = Vec::new();
  548. for _ in 0..200usize {
  549. full_bank.push(entity_gateway.create_item(
  550. item::NewItemEntity {
  551. item: item::ItemDetail::Weapon(
  552. item::weapon::Weapon {
  553. weapon: item::weapon::WeaponType::Vulcan,
  554. grind: 0,
  555. special: None,
  556. attrs: [None, None, None],
  557. tekked: true,
  558. }
  559. ),
  560. }).await.unwrap());
  561. }
  562. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap();
  563. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(full_bank), item::BankName("".into())).await.unwrap();
  564. let mut ship = Box::new(ShipServerState::builder()
  565. .gateway(entity_gateway.clone())
  566. .build());
  567. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  568. join_lobby(&mut ship, ClientId(1)).await;
  569. create_room(&mut ship, ClientId(1), "room", "").await;
  570. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  571. client: 0,
  572. target: 0,
  573. unknown: 0,
  574. })))).await.unwrap().for_each(drop);
  575. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  576. client: 0,
  577. target: 0,
  578. item_id: 0x10000,
  579. action: 0,
  580. item_amount: 2,
  581. meseta_amount: 0,
  582. unknown: 0,
  583. })))).await;
  584. assert!(packets.is_err());
  585. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  586. assert_eq!(bank_items.items.len(), 200);
  587. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  588. assert_eq!(inventory_items.items.len(), 1);
  589. inventory_items.items[0].with_stacked(|items| {
  590. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  591. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  592. }).unwrap();
  593. }
  594. #[async_std::test]
  595. async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() {
  596. let mut entity_gateway = InMemoryGateway::default();
  597. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  598. let mut monomates = Vec::new();
  599. for _ in 0..2usize {
  600. monomates.push(entity_gateway.create_item(
  601. item::NewItemEntity {
  602. item: item::ItemDetail::Tool(
  603. item::tool::Tool {
  604. tool: item::tool::ToolType::Monomate,
  605. }
  606. ),
  607. }).await.unwrap());
  608. }
  609. let mut bank_monomates = Vec::new();
  610. for _ in 0..2usize {
  611. bank_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. }
  617. ),
  618. }).await.unwrap());
  619. }
  620. let mut almost_full_bank: Vec<item::BankItemEntity> = Vec::new();
  621. for _ in 0..199usize {
  622. almost_full_bank.push(entity_gateway.create_item(
  623. item::NewItemEntity {
  624. item: item::ItemDetail::Weapon(
  625. item::weapon::Weapon {
  626. weapon: item::weapon::WeaponType::Vulcan,
  627. grind: 0,
  628. special: None,
  629. attrs: [None, None, None],
  630. tekked: true,
  631. }
  632. ),
  633. }).await.unwrap().into());
  634. }
  635. almost_full_bank.push(bank_monomates.into());
  636. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap();
  637. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(almost_full_bank), item::BankName("".into())).await.unwrap();
  638. let mut ship = Box::new(ShipServerState::builder()
  639. .gateway(entity_gateway.clone())
  640. .build());
  641. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  642. join_lobby(&mut ship, ClientId(1)).await;
  643. create_room(&mut ship, ClientId(1), "room", "").await;
  644. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  645. client: 0,
  646. target: 0,
  647. unknown: 0,
  648. })))).await.unwrap().for_each(drop);
  649. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  650. client: 0,
  651. target: 0,
  652. item_id: 0x10000,
  653. action: 0,
  654. item_amount: 2,
  655. meseta_amount: 0,
  656. unknown: 0,
  657. })))).await.unwrap().for_each(drop);
  658. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  659. assert_eq!(bank_items.items.len(), 200);
  660. bank_items.items[199].with_stacked(|items| {
  661. assert_eq!(items.len(), 4);
  662. }).unwrap();
  663. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  664. assert_eq!(inventory_items.items.len(), 0);
  665. }
  666. #[async_std::test]
  667. async fn test_deposit_meseta() {
  668. let mut entity_gateway = InMemoryGateway::default();
  669. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  670. char1.meseta = 300;
  671. entity_gateway.save_character(&char1).await.unwrap();
  672. let mut ship = Box::new(ShipServerState::builder()
  673. .gateway(entity_gateway.clone())
  674. .build());
  675. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  676. join_lobby(&mut ship, ClientId(1)).await;
  677. create_room(&mut ship, ClientId(1), "room", "").await;
  678. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  679. client: 0,
  680. target: 0,
  681. unknown: 0,
  682. })))).await.unwrap().for_each(drop);
  683. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  684. client: 0,
  685. target: 0,
  686. item_id: 0xFFFFFFFF,
  687. action: 0,
  688. item_amount: 0,
  689. meseta_amount: 23,
  690. unknown: 0,
  691. })))).await.unwrap().for_each(drop);
  692. let characters = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  693. let char = characters[0].as_ref().unwrap();
  694. assert!(char.meseta == 277);
  695. assert!(char.bank_meseta == 23);
  696. }
  697. #[async_std::test]
  698. async fn test_deposit_too_much_meseta() {
  699. let mut entity_gateway = InMemoryGateway::default();
  700. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  701. char1.meseta = 300;
  702. char1.bank_meseta = 999980;
  703. entity_gateway.save_character(&char1).await.unwrap();
  704. let mut ship = Box::new(ShipServerState::builder()
  705. .gateway(entity_gateway.clone())
  706. .build());
  707. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  708. join_lobby(&mut ship, ClientId(1)).await;
  709. create_room(&mut ship, ClientId(1), "room", "").await;
  710. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  711. client: 0,
  712. target: 0,
  713. unknown: 0,
  714. })))).await.unwrap().for_each(drop);
  715. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  716. client: 0,
  717. target: 0,
  718. item_id: 0xFFFFFFFF,
  719. action: 0,
  720. item_amount: 0,
  721. meseta_amount: 23,
  722. unknown: 0,
  723. })))).await.unwrap().for_each(drop);
  724. let characters = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  725. let char = characters[0].as_ref().unwrap();
  726. assert!(char.meseta == 300);
  727. assert!(char.bank_meseta == 999980);
  728. }
  729. #[async_std::test]
  730. async fn test_deposit_meseta_when_bank_is_maxed() {
  731. let mut entity_gateway = InMemoryGateway::default();
  732. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  733. char1.meseta = 300;
  734. char1.bank_meseta = 999999;
  735. entity_gateway.save_character(&char1).await.unwrap();
  736. let mut ship = Box::new(ShipServerState::builder()
  737. .gateway(entity_gateway.clone())
  738. .build());
  739. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  740. join_lobby(&mut ship, ClientId(1)).await;
  741. create_room(&mut ship, ClientId(1), "room", "").await;
  742. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  743. client: 0,
  744. target: 0,
  745. unknown: 0,
  746. })))).await.unwrap().for_each(drop);
  747. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  748. client: 0,
  749. target: 0,
  750. item_id: 0xFFFFFFFF,
  751. action: 0,
  752. item_amount: 0,
  753. meseta_amount: 23,
  754. unknown: 0,
  755. })))).await.unwrap().for_each(drop);
  756. let characters = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  757. let char = characters[0].as_ref().unwrap();
  758. assert!(char.meseta == 300);
  759. assert!(char.bank_meseta == 999999);
  760. }
  761. #[async_std::test]
  762. async fn test_withdraw_individual_item() {
  763. let mut entity_gateway = InMemoryGateway::default();
  764. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  765. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  766. let mut bank = Vec::new();
  767. bank.push(entity_gateway.create_item(
  768. item::NewItemEntity {
  769. item: item::ItemDetail::Weapon(
  770. item::weapon::Weapon {
  771. weapon: item::weapon::WeaponType::Saber,
  772. grind: 0,
  773. special: None,
  774. attrs: [None, None, None],
  775. tekked: true,
  776. }
  777. ),
  778. }).await.unwrap());
  779. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), item::BankName("".into())).await.unwrap();
  780. let mut ship = Box::new(ShipServerState::builder()
  781. .gateway(entity_gateway.clone())
  782. .build());
  783. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  784. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  785. join_lobby(&mut ship, ClientId(1)).await;
  786. join_lobby(&mut ship, ClientId(2)).await;
  787. create_room(&mut ship, ClientId(1), "room", "").await;
  788. join_room(&mut ship, ClientId(2), 0).await;
  789. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  790. client: 0,
  791. target: 0,
  792. unknown: 0,
  793. })))).await.unwrap().for_each(drop);
  794. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  795. client: 0,
  796. target: 0,
  797. item_id: 0x20000,
  798. action: 1,
  799. item_amount: 0,
  800. meseta_amount: 0,
  801. unknown: 0,
  802. })))).await.unwrap().collect::<Vec<_>>();
  803. assert!(packets.len() == 2);
  804. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  805. if create_item.item_id == 0x20000
  806. ));
  807. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  808. assert_eq!(inventory_items.items.len(), 1);
  809. inventory_items.items[0].with_individual(|item| {
  810. assert_eq!(item.id, item::ItemEntityId(1));
  811. }).unwrap();
  812. }
  813. #[async_std::test]
  814. async fn test_withdraw_stacked_item() {
  815. let mut entity_gateway = InMemoryGateway::default();
  816. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  817. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  818. let mut monomates = Vec::new();
  819. for _ in 0..3usize {
  820. monomates.push(entity_gateway.create_item(
  821. item::NewItemEntity {
  822. item: item::ItemDetail::Tool(
  823. item::tool::Tool {
  824. tool: item::tool::ToolType::Monomate,
  825. }
  826. ),
  827. }).await.unwrap());
  828. }
  829. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), item::BankName("".into())).await.unwrap();
  830. let mut ship = Box::new(ShipServerState::builder()
  831. .gateway(entity_gateway.clone())
  832. .build());
  833. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  834. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  835. join_lobby(&mut ship, ClientId(1)).await;
  836. join_lobby(&mut ship, ClientId(2)).await;
  837. create_room(&mut ship, ClientId(1), "room", "").await;
  838. join_room(&mut ship, ClientId(2), 0).await;
  839. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  840. client: 0,
  841. target: 0,
  842. unknown: 0,
  843. })))).await.unwrap().for_each(drop);
  844. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  845. client: 0,
  846. target: 0,
  847. item_id: 0x20000,
  848. action: 1,
  849. item_amount: 3,
  850. meseta_amount: 0,
  851. unknown: 0,
  852. })))).await.unwrap().collect::<Vec<_>>();
  853. assert!(packets.len() == 2);
  854. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  855. if create_item.item_id == 0x10002
  856. ));
  857. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  858. assert_eq!(inventory_items.items.len(), 1);
  859. inventory_items.items[0].with_stacked(|items| {
  860. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  861. vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]);
  862. }).unwrap();
  863. }
  864. #[async_std::test]
  865. async fn test_withdraw_partial_stacked_item() {
  866. let mut entity_gateway = InMemoryGateway::default();
  867. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  868. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  869. let mut monomates = Vec::new();
  870. for _ in 0..3usize {
  871. monomates.push(entity_gateway.create_item(
  872. item::NewItemEntity {
  873. item: item::ItemDetail::Tool(
  874. item::tool::Tool {
  875. tool: item::tool::ToolType::Monomate,
  876. }
  877. ),
  878. }).await.unwrap());
  879. }
  880. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), 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: 2,
  901. meseta_amount: 0,
  902. unknown: 0,
  903. })))).await.unwrap().collect::<Vec<_>>();
  904. assert!(packets.len() == 2);
  905. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  906. if create_item.item_id == 0x10002
  907. ));
  908. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  909. assert_eq!(bank_items.items.len(), 1);
  910. bank_items.items[0].with_stacked(|items| {
  911. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  912. vec![item::ItemEntityId(3)]);
  913. }).unwrap();
  914. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  915. assert_eq!(inventory_items.items.len(), 1);
  916. inventory_items.items[0].with_stacked(|items| {
  917. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  918. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  919. }).unwrap();
  920. }
  921. #[async_std::test]
  922. async fn test_withdraw_stacked_item_with_stack_already_in_inventory() {
  923. let mut entity_gateway = InMemoryGateway::default();
  924. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  925. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  926. let mut inventory_monomates = Vec::new();
  927. let mut bank_monomates = Vec::new();
  928. for _ in 0..2usize {
  929. inventory_monomates.push(entity_gateway.create_item(
  930. item::NewItemEntity {
  931. item: item::ItemDetail::Tool(
  932. item::tool::Tool {
  933. tool: item::tool::ToolType::Monomate,
  934. }
  935. ),
  936. }).await.unwrap());
  937. bank_monomates.push(entity_gateway.create_item(
  938. item::NewItemEntity {
  939. item: item::ItemDetail::Tool(
  940. item::tool::Tool {
  941. tool: item::tool::ToolType::Monomate,
  942. }
  943. ),
  944. }).await.unwrap());
  945. }
  946. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap();
  947. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), item::BankName("".into())).await.unwrap();
  948. let mut ship = Box::new(ShipServerState::builder()
  949. .gateway(entity_gateway.clone())
  950. .build());
  951. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  952. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  953. join_lobby(&mut ship, ClientId(1)).await;
  954. join_lobby(&mut ship, ClientId(2)).await;
  955. create_room(&mut ship, ClientId(1), "room", "").await;
  956. join_room(&mut ship, ClientId(2), 0).await;
  957. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  958. client: 0,
  959. target: 0,
  960. unknown: 0,
  961. })))).await.unwrap().for_each(drop);
  962. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  963. client: 0,
  964. target: 0,
  965. item_id: 0x20000,
  966. action: 1,
  967. item_amount: 2,
  968. meseta_amount: 0,
  969. unknown: 0,
  970. })))).await.unwrap().collect::<Vec<_>>();
  971. assert!(packets.len() == 2);
  972. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  973. if create_item.item_id == 0x10000
  974. ));
  975. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  976. assert_eq!(bank_items.items.len(), 0);
  977. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  978. assert_eq!(inventory_items.items.len(), 1);
  979. inventory_items.items[0].with_stacked(|items| {
  980. assert_eq!(items.iter().map(|i| i.id).collect::<BTreeSet<_>>(),
  981. vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)].into_iter().collect::<BTreeSet<_>>());
  982. }).unwrap();
  983. }
  984. #[async_std::test]
  985. async fn test_withdraw_stacked_item_with_full_stack_in_inventory() {
  986. let mut entity_gateway = InMemoryGateway::default();
  987. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  988. let mut bank_monomates = Vec::new();
  989. for _ in 0..2usize {
  990. bank_monomates.push(entity_gateway.create_item(
  991. item::NewItemEntity {
  992. item: item::ItemDetail::Tool(
  993. item::tool::Tool {
  994. tool: item::tool::ToolType::Monomate,
  995. }
  996. ),
  997. }).await.unwrap());
  998. }
  999. let mut inventory_monomates = Vec::new();
  1000. for _ in 0..10usize {
  1001. inventory_monomates.push(entity_gateway.create_item(
  1002. item::NewItemEntity {
  1003. item: item::ItemDetail::Tool(
  1004. item::tool::Tool {
  1005. tool: item::tool::ToolType::Monomate,
  1006. }
  1007. ),
  1008. }).await.unwrap());
  1009. }
  1010. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap();
  1011. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), item::BankName("".into())).await.unwrap();
  1012. let mut ship = Box::new(ShipServerState::builder()
  1013. .gateway(entity_gateway.clone())
  1014. .build());
  1015. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1016. join_lobby(&mut ship, ClientId(1)).await;
  1017. create_room(&mut ship, ClientId(1), "room", "").await;
  1018. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1019. client: 0,
  1020. target: 0,
  1021. unknown: 0,
  1022. })))).await.unwrap().for_each(drop);
  1023. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1024. client: 0,
  1025. target: 0,
  1026. item_id: 0x20000,
  1027. action: 1,
  1028. item_amount: 2,
  1029. meseta_amount: 0,
  1030. unknown: 0,
  1031. })))).await;
  1032. assert!(packets.is_err());
  1033. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  1034. assert_eq!(bank_items.items.len(), 1);
  1035. bank_items.items[0].with_stacked(|items| {
  1036. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  1037. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  1038. }).unwrap();
  1039. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1040. assert_eq!(inventory_items.items.len(), 1);
  1041. inventory_items.items[0].with_stacked(|items| {
  1042. assert_eq!(items.len(), 10);
  1043. }).unwrap();
  1044. }
  1045. #[async_std::test]
  1046. async fn test_withdraw_individual_item_in_full_inventory() {
  1047. let mut entity_gateway = InMemoryGateway::default();
  1048. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1049. let mut bank = Vec::new();
  1050. bank.push(entity_gateway.create_item(
  1051. item::NewItemEntity {
  1052. item: item::ItemDetail::Weapon(
  1053. item::weapon::Weapon {
  1054. weapon: item::weapon::WeaponType::Vulcan,
  1055. grind: 0,
  1056. special: None,
  1057. attrs: [None, None, None],
  1058. tekked: true,
  1059. }
  1060. ),
  1061. }).await.unwrap());
  1062. let mut inventory = Vec::new();
  1063. for _ in 0..30usize {
  1064. inventory.push(entity_gateway.create_item(
  1065. item::NewItemEntity {
  1066. item: item::ItemDetail::Weapon(
  1067. item::weapon::Weapon {
  1068. weapon: item::weapon::WeaponType::Vulcan,
  1069. grind: 0,
  1070. special: None,
  1071. attrs: [None, None, None],
  1072. tekked: true,
  1073. }
  1074. ),
  1075. }).await.unwrap());
  1076. }
  1077. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap();
  1078. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), item::BankName("".into())).await.unwrap();
  1079. let mut ship = Box::new(ShipServerState::builder()
  1080. .gateway(entity_gateway.clone())
  1081. .build());
  1082. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1083. join_lobby(&mut ship, ClientId(1)).await;
  1084. create_room(&mut ship, ClientId(1), "room", "").await;
  1085. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1086. client: 0,
  1087. target: 0,
  1088. unknown: 0,
  1089. })))).await.unwrap().for_each(drop);
  1090. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1091. client: 0,
  1092. target: 0,
  1093. item_id: 0x20000,
  1094. action: 1,
  1095. item_amount: 0,
  1096. meseta_amount: 0,
  1097. unknown: 0,
  1098. })))).await;
  1099. assert!(packets.is_err());
  1100. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  1101. assert_eq!(bank_items.items.len(), 1);
  1102. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1103. assert_eq!(inventory_items.items.len(), 30);
  1104. }
  1105. #[async_std::test]
  1106. async fn test_withdraw_stacked_item_in_full_inventory() {
  1107. let mut entity_gateway = InMemoryGateway::default();
  1108. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1109. let mut monomates = Vec::new();
  1110. for _ in 0..2usize {
  1111. monomates.push(entity_gateway.create_item(
  1112. item::NewItemEntity {
  1113. item: item::ItemDetail::Tool(
  1114. item::tool::Tool {
  1115. tool: item::tool::ToolType::Monomate,
  1116. }
  1117. ),
  1118. }).await.unwrap());
  1119. }
  1120. let mut inventory = Vec::new();
  1121. for _ in 0..30usize {
  1122. inventory.push(entity_gateway.create_item(
  1123. item::NewItemEntity {
  1124. item: item::ItemDetail::Weapon(
  1125. item::weapon::Weapon {
  1126. weapon: item::weapon::WeaponType::Vulcan,
  1127. grind: 0,
  1128. special: None,
  1129. attrs: [None, None, None],
  1130. tekked: true,
  1131. }
  1132. ),
  1133. }).await.unwrap());
  1134. }
  1135. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap();
  1136. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), item::BankName("".into())).await.unwrap();
  1137. let mut ship = Box::new(ShipServerState::builder()
  1138. .gateway(entity_gateway.clone())
  1139. .build());
  1140. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1141. join_lobby(&mut ship, ClientId(1)).await;
  1142. create_room(&mut ship, ClientId(1), "room", "").await;
  1143. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1144. client: 0,
  1145. target: 0,
  1146. unknown: 0,
  1147. })))).await.unwrap().for_each(drop);
  1148. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1149. client: 0,
  1150. target: 0,
  1151. item_id: 0x20000,
  1152. action: 1,
  1153. item_amount: 2,
  1154. meseta_amount: 0,
  1155. unknown: 0,
  1156. })))).await;
  1157. assert!(packets.is_err());
  1158. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  1159. assert_eq!(bank_items.items.len(), 1);
  1160. bank_items.items[0].with_stacked(|items| {
  1161. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  1162. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  1163. }).unwrap();
  1164. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1165. assert_eq!(inventory_items.items.len(), 30);
  1166. }
  1167. #[async_std::test]
  1168. async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() {
  1169. let mut entity_gateway = InMemoryGateway::default();
  1170. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1171. let mut bank_item = Vec::new();
  1172. for _ in 0..2usize {
  1173. bank_item.push(entity_gateway.create_item(
  1174. item::NewItemEntity {
  1175. item: item::ItemDetail::Tool(
  1176. item::tool::Tool {
  1177. tool: item::tool::ToolType::Monomate,
  1178. }
  1179. ),
  1180. }).await.unwrap());
  1181. }
  1182. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_item]), item::BankName("".into())).await.unwrap();
  1183. let mut items = Vec::new();
  1184. for i in 0..29usize {
  1185. items.push(entity_gateway.create_item(
  1186. item::NewItemEntity {
  1187. item: item::ItemDetail::Weapon(
  1188. item::weapon::Weapon {
  1189. weapon: item::weapon::WeaponType::Vulcan,
  1190. grind: 0,
  1191. special: None,
  1192. attrs: [None, None, None],
  1193. tekked: true,
  1194. }
  1195. ),
  1196. }).await.unwrap().into());
  1197. }
  1198. let mut item29 = Vec::new();
  1199. for _ in 0..2usize {
  1200. item29.push(entity_gateway.create_item(
  1201. item::NewItemEntity {
  1202. item: item::ItemDetail::Tool(
  1203. item::tool::Tool {
  1204. tool: item::tool::ToolType::Monomate,
  1205. }
  1206. ),
  1207. }).await.unwrap());
  1208. }
  1209. items.push(item::InventoryItemEntity::Stacked(item29));
  1210. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(items)).await.unwrap();
  1211. let mut ship = Box::new(ShipServerState::builder()
  1212. .gateway(entity_gateway.clone())
  1213. .build());
  1214. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1215. join_lobby(&mut ship, ClientId(1)).await;
  1216. create_room(&mut ship, ClientId(1), "room", "").await;
  1217. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1218. client: 0,
  1219. target: 0,
  1220. unknown: 0,
  1221. })))).await.unwrap().for_each(drop);
  1222. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1223. client: 0,
  1224. target: 0,
  1225. item_id: 0x20000,
  1226. action: 1,
  1227. item_amount: 2,
  1228. meseta_amount: 0,
  1229. unknown: 0,
  1230. })))).await.unwrap().for_each(drop);
  1231. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  1232. assert!(bank_items.items.len() == 0);
  1233. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1234. assert!(inventory_items.items.len() == 30);
  1235. match &inventory_items.items[29] {
  1236. item::InventoryItemEntity::Stacked(items) => {
  1237. assert_eq!(items.len(), 4);
  1238. },
  1239. _ => panic!(),
  1240. }
  1241. }
  1242. #[async_std::test]
  1243. async fn test_withdraw_meseta() {
  1244. let mut entity_gateway = InMemoryGateway::default();
  1245. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1246. char1.bank_meseta = 300;
  1247. entity_gateway.save_character(&char1).await.unwrap();
  1248. let mut ship = Box::new(ShipServerState::builder()
  1249. .gateway(entity_gateway.clone())
  1250. .build());
  1251. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1252. join_lobby(&mut ship, ClientId(1)).await;
  1253. create_room(&mut ship, ClientId(1), "room", "").await;
  1254. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1255. client: 0,
  1256. target: 0,
  1257. unknown: 0,
  1258. })))).await.unwrap().for_each(drop);
  1259. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1260. client: 0,
  1261. target: 0,
  1262. item_id: 0xFFFFFFFF,
  1263. action: 1,
  1264. item_amount: 0,
  1265. meseta_amount: 23,
  1266. unknown: 0,
  1267. })))).await.unwrap().for_each(drop);
  1268. let characters = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  1269. let char = characters[0].as_ref().unwrap();
  1270. assert!(char.meseta == 23);
  1271. assert!(char.bank_meseta == 277);
  1272. }
  1273. #[async_std::test]
  1274. async fn test_withdraw_too_much_meseta() {
  1275. let mut entity_gateway = InMemoryGateway::default();
  1276. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1277. char1.meseta = 999980;
  1278. char1.bank_meseta = 300;
  1279. entity_gateway.save_character(&char1).await.unwrap();
  1280. let mut ship = Box::new(ShipServerState::builder()
  1281. .gateway(entity_gateway.clone())
  1282. .build());
  1283. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1284. join_lobby(&mut ship, ClientId(1)).await;
  1285. create_room(&mut ship, ClientId(1), "room", "").await;
  1286. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1287. client: 0,
  1288. target: 0,
  1289. unknown: 0,
  1290. })))).await.unwrap().for_each(drop);
  1291. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1292. client: 0,
  1293. target: 0,
  1294. item_id: 0xFFFFFFFF,
  1295. action: 1,
  1296. item_amount: 0,
  1297. meseta_amount: 23,
  1298. unknown: 0,
  1299. })))).await.unwrap().for_each(drop);
  1300. let characters = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  1301. let char = characters[0].as_ref().unwrap();
  1302. assert!(char.meseta == 999980);
  1303. assert!(char.bank_meseta == 300);
  1304. }
  1305. #[async_std::test]
  1306. async fn test_withdraw_meseta_inventory_is_maxed() {
  1307. let mut entity_gateway = InMemoryGateway::default();
  1308. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1309. char1.meseta = 999999;
  1310. char1.bank_meseta = 300;
  1311. entity_gateway.save_character(&char1).await.unwrap();
  1312. let mut ship = Box::new(ShipServerState::builder()
  1313. .gateway(entity_gateway.clone())
  1314. .build());
  1315. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1316. join_lobby(&mut ship, ClientId(1)).await;
  1317. create_room(&mut ship, ClientId(1), "room", "").await;
  1318. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1319. client: 0,
  1320. target: 0,
  1321. unknown: 0,
  1322. })))).await.unwrap().for_each(drop);
  1323. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1324. client: 0,
  1325. target: 0,
  1326. item_id: 0xFFFFFFFF,
  1327. action: 1,
  1328. item_amount: 0,
  1329. meseta_amount: 23,
  1330. unknown: 0,
  1331. })))).await.unwrap().for_each(drop);
  1332. let characters = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  1333. let char = characters[0].as_ref().unwrap();
  1334. assert!(char.meseta == 999999);
  1335. assert!(char.bank_meseta == 300);
  1336. }