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.

1567 lines
60 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
  1. use std::collections::BTreeSet;
  2. use elseware::common::serverstate::{ClientId, ServerState};
  3. use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
  4. use elseware::entity::item;
  5. use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket};
  6. use libpso::packet::ship::*;
  7. use libpso::packet::messages::*;
  8. #[path = "common.rs"]
  9. mod common;
  10. use common::*;
  11. #[async_std::test]
  12. async fn test_bank_items_sent_in_character_login() {
  13. let mut entity_gateway = InMemoryGateway::default();
  14. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").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, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  670. entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap();
  671. let mut ship = Box::new(ShipServerState::builder()
  672. .gateway(entity_gateway.clone())
  673. .build());
  674. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  675. join_lobby(&mut ship, ClientId(1)).await;
  676. create_room(&mut ship, ClientId(1), "room", "").await;
  677. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  678. client: 0,
  679. target: 0,
  680. unknown: 0,
  681. })))).await.unwrap().for_each(drop);
  682. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  683. client: 0,
  684. target: 0,
  685. item_id: 0xFFFFFFFF,
  686. action: 0,
  687. item_amount: 0,
  688. meseta_amount: 23,
  689. unknown: 0,
  690. })))).await.unwrap().for_each(drop);
  691. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  692. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, item::BankName("".into())).await.unwrap();
  693. assert!(c1_meseta.0 == 277);
  694. assert!(c1_bank_meseta.0 == 23);
  695. }
  696. #[async_std::test]
  697. async fn test_deposit_too_much_meseta() {
  698. let mut entity_gateway = InMemoryGateway::default();
  699. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  700. entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap();
  701. entity_gateway.set_bank_meseta(&char1.id, item::BankName("".into()), item::Meseta(999980)).await.unwrap();
  702. let mut ship = Box::new(ShipServerState::builder()
  703. .gateway(entity_gateway.clone())
  704. .build());
  705. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  706. join_lobby(&mut ship, ClientId(1)).await;
  707. create_room(&mut ship, ClientId(1), "room", "").await;
  708. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  709. client: 0,
  710. target: 0,
  711. unknown: 0,
  712. })))).await.unwrap().for_each(drop);
  713. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  714. client: 0,
  715. target: 0,
  716. item_id: 0xFFFFFFFF,
  717. action: 0,
  718. item_amount: 0,
  719. meseta_amount: 23,
  720. unknown: 0,
  721. })))).await.unwrap().for_each(drop);
  722. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  723. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, item::BankName("".into())).await.unwrap();
  724. assert!(c1_meseta.0 == 300);
  725. assert!(c1_bank_meseta.0 == 999980);
  726. }
  727. #[async_std::test]
  728. async fn test_deposit_meseta_when_bank_is_maxed() {
  729. let mut entity_gateway = InMemoryGateway::default();
  730. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  731. entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap();
  732. entity_gateway.set_bank_meseta(&char1.id, item::BankName("".into()), item::Meseta(999999)).await.unwrap();
  733. let mut ship = Box::new(ShipServerState::builder()
  734. .gateway(entity_gateway.clone())
  735. .build());
  736. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  737. join_lobby(&mut ship, ClientId(1)).await;
  738. create_room(&mut ship, ClientId(1), "room", "").await;
  739. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  740. client: 0,
  741. target: 0,
  742. unknown: 0,
  743. })))).await.unwrap().for_each(drop);
  744. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  745. client: 0,
  746. target: 0,
  747. item_id: 0xFFFFFFFF,
  748. action: 0,
  749. item_amount: 0,
  750. meseta_amount: 23,
  751. unknown: 0,
  752. })))).await.unwrap().for_each(drop);
  753. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  754. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, item::BankName("".into())).await.unwrap();
  755. assert!(c1_meseta.0 == 300);
  756. assert!(c1_bank_meseta.0 == 999999);
  757. }
  758. #[async_std::test]
  759. async fn test_withdraw_individual_item() {
  760. let mut entity_gateway = InMemoryGateway::default();
  761. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  762. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  763. let mut bank = Vec::new();
  764. bank.push(entity_gateway.create_item(
  765. item::NewItemEntity {
  766. item: item::ItemDetail::Weapon(
  767. item::weapon::Weapon {
  768. weapon: item::weapon::WeaponType::Saber,
  769. grind: 0,
  770. special: None,
  771. attrs: [None, None, None],
  772. tekked: true,
  773. }
  774. ),
  775. }).await.unwrap());
  776. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), item::BankName("".into())).await.unwrap();
  777. let mut ship = Box::new(ShipServerState::builder()
  778. .gateway(entity_gateway.clone())
  779. .build());
  780. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  781. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  782. join_lobby(&mut ship, ClientId(1)).await;
  783. join_lobby(&mut ship, ClientId(2)).await;
  784. create_room(&mut ship, ClientId(1), "room", "").await;
  785. join_room(&mut ship, ClientId(2), 0).await;
  786. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  787. client: 0,
  788. target: 0,
  789. unknown: 0,
  790. })))).await.unwrap().for_each(drop);
  791. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  792. client: 0,
  793. target: 0,
  794. item_id: 0x20000,
  795. action: 1,
  796. item_amount: 0,
  797. meseta_amount: 0,
  798. unknown: 0,
  799. })))).await.unwrap().collect::<Vec<_>>();
  800. assert!(packets.len() == 2);
  801. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  802. if create_item.item_id == 0x20000
  803. ));
  804. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  805. assert_eq!(inventory_items.items.len(), 1);
  806. inventory_items.items[0].with_individual(|item| {
  807. assert_eq!(item.id, item::ItemEntityId(1));
  808. }).unwrap();
  809. }
  810. #[async_std::test]
  811. async fn test_withdraw_stacked_item() {
  812. let mut entity_gateway = InMemoryGateway::default();
  813. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  814. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  815. let mut monomates = Vec::new();
  816. for _ in 0..3usize {
  817. monomates.push(entity_gateway.create_item(
  818. item::NewItemEntity {
  819. item: item::ItemDetail::Tool(
  820. item::tool::Tool {
  821. tool: item::tool::ToolType::Monomate,
  822. }
  823. ),
  824. }).await.unwrap());
  825. }
  826. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), item::BankName("".into())).await.unwrap();
  827. let mut ship = Box::new(ShipServerState::builder()
  828. .gateway(entity_gateway.clone())
  829. .build());
  830. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  831. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  832. join_lobby(&mut ship, ClientId(1)).await;
  833. join_lobby(&mut ship, ClientId(2)).await;
  834. create_room(&mut ship, ClientId(1), "room", "").await;
  835. join_room(&mut ship, ClientId(2), 0).await;
  836. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  837. client: 0,
  838. target: 0,
  839. unknown: 0,
  840. })))).await.unwrap().for_each(drop);
  841. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  842. client: 0,
  843. target: 0,
  844. item_id: 0x20000,
  845. action: 1,
  846. item_amount: 3,
  847. meseta_amount: 0,
  848. unknown: 0,
  849. })))).await.unwrap().collect::<Vec<_>>();
  850. assert!(packets.len() == 2);
  851. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  852. if create_item.item_id == 0x10002
  853. ));
  854. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  855. assert_eq!(inventory_items.items.len(), 1);
  856. inventory_items.items[0].with_stacked(|items| {
  857. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  858. vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]);
  859. }).unwrap();
  860. }
  861. #[async_std::test]
  862. async fn test_withdraw_partial_stacked_item() {
  863. let mut entity_gateway = InMemoryGateway::default();
  864. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  865. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  866. let mut monomates = Vec::new();
  867. for _ in 0..3usize {
  868. monomates.push(entity_gateway.create_item(
  869. item::NewItemEntity {
  870. item: item::ItemDetail::Tool(
  871. item::tool::Tool {
  872. tool: item::tool::ToolType::Monomate,
  873. }
  874. ),
  875. }).await.unwrap());
  876. }
  877. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), item::BankName("".into())).await.unwrap();
  878. let mut ship = Box::new(ShipServerState::builder()
  879. .gateway(entity_gateway.clone())
  880. .build());
  881. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  882. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  883. join_lobby(&mut ship, ClientId(1)).await;
  884. join_lobby(&mut ship, ClientId(2)).await;
  885. create_room(&mut ship, ClientId(1), "room", "").await;
  886. join_room(&mut ship, ClientId(2), 0).await;
  887. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  888. client: 0,
  889. target: 0,
  890. unknown: 0,
  891. })))).await.unwrap().for_each(drop);
  892. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  893. client: 0,
  894. target: 0,
  895. item_id: 0x20000,
  896. action: 1,
  897. item_amount: 2,
  898. meseta_amount: 0,
  899. unknown: 0,
  900. })))).await.unwrap().collect::<Vec<_>>();
  901. assert!(packets.len() == 2);
  902. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  903. if create_item.item_id == 0x10002
  904. ));
  905. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  906. assert_eq!(bank_items.items.len(), 1);
  907. bank_items.items[0].with_stacked(|items| {
  908. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  909. vec![item::ItemEntityId(3)]);
  910. }).unwrap();
  911. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  912. assert_eq!(inventory_items.items.len(), 1);
  913. inventory_items.items[0].with_stacked(|items| {
  914. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  915. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  916. }).unwrap();
  917. }
  918. #[async_std::test]
  919. async fn test_withdraw_stacked_item_with_stack_already_in_inventory() {
  920. let mut entity_gateway = InMemoryGateway::default();
  921. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  922. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  923. let mut inventory_monomates = Vec::new();
  924. let mut bank_monomates = Vec::new();
  925. for _ in 0..2usize {
  926. inventory_monomates.push(entity_gateway.create_item(
  927. item::NewItemEntity {
  928. item: item::ItemDetail::Tool(
  929. item::tool::Tool {
  930. tool: item::tool::ToolType::Monomate,
  931. }
  932. ),
  933. }).await.unwrap());
  934. bank_monomates.push(entity_gateway.create_item(
  935. item::NewItemEntity {
  936. item: item::ItemDetail::Tool(
  937. item::tool::Tool {
  938. tool: item::tool::ToolType::Monomate,
  939. }
  940. ),
  941. }).await.unwrap());
  942. }
  943. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap();
  944. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), item::BankName("".into())).await.unwrap();
  945. let mut ship = Box::new(ShipServerState::builder()
  946. .gateway(entity_gateway.clone())
  947. .build());
  948. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  949. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  950. join_lobby(&mut ship, ClientId(1)).await;
  951. join_lobby(&mut ship, ClientId(2)).await;
  952. create_room(&mut ship, ClientId(1), "room", "").await;
  953. join_room(&mut ship, ClientId(2), 0).await;
  954. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  955. client: 0,
  956. target: 0,
  957. unknown: 0,
  958. })))).await.unwrap().for_each(drop);
  959. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  960. client: 0,
  961. target: 0,
  962. item_id: 0x20000,
  963. action: 1,
  964. item_amount: 2,
  965. meseta_amount: 0,
  966. unknown: 0,
  967. })))).await.unwrap().collect::<Vec<_>>();
  968. assert!(packets.len() == 2);
  969. assert!(matches!(&packets[1], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
  970. if create_item.item_id == 0x10000
  971. ));
  972. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  973. assert_eq!(bank_items.items.len(), 0);
  974. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  975. assert_eq!(inventory_items.items.len(), 1);
  976. inventory_items.items[0].with_stacked(|items| {
  977. assert_eq!(items.iter().map(|i| i.id).collect::<BTreeSet<_>>(),
  978. vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)].into_iter().collect::<BTreeSet<_>>());
  979. }).unwrap();
  980. }
  981. #[async_std::test]
  982. async fn test_withdraw_stacked_item_with_full_stack_in_inventory() {
  983. let mut entity_gateway = InMemoryGateway::default();
  984. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  985. let mut bank_monomates = Vec::new();
  986. for _ in 0..2usize {
  987. bank_monomates.push(entity_gateway.create_item(
  988. item::NewItemEntity {
  989. item: item::ItemDetail::Tool(
  990. item::tool::Tool {
  991. tool: item::tool::ToolType::Monomate,
  992. }
  993. ),
  994. }).await.unwrap());
  995. }
  996. let mut inventory_monomates = Vec::new();
  997. for _ in 0..10usize {
  998. inventory_monomates.push(entity_gateway.create_item(
  999. item::NewItemEntity {
  1000. item: item::ItemDetail::Tool(
  1001. item::tool::Tool {
  1002. tool: item::tool::ToolType::Monomate,
  1003. }
  1004. ),
  1005. }).await.unwrap());
  1006. }
  1007. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap();
  1008. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), item::BankName("".into())).await.unwrap();
  1009. let mut ship = Box::new(ShipServerState::builder()
  1010. .gateway(entity_gateway.clone())
  1011. .build());
  1012. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1013. join_lobby(&mut ship, ClientId(1)).await;
  1014. create_room(&mut ship, ClientId(1), "room", "").await;
  1015. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1016. client: 0,
  1017. target: 0,
  1018. unknown: 0,
  1019. })))).await.unwrap().for_each(drop);
  1020. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1021. client: 0,
  1022. target: 0,
  1023. item_id: 0x20000,
  1024. action: 1,
  1025. item_amount: 2,
  1026. meseta_amount: 0,
  1027. unknown: 0,
  1028. })))).await;
  1029. assert!(packets.is_err());
  1030. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  1031. assert_eq!(bank_items.items.len(), 1);
  1032. bank_items.items[0].with_stacked(|items| {
  1033. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  1034. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  1035. }).unwrap();
  1036. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1037. assert_eq!(inventory_items.items.len(), 1);
  1038. inventory_items.items[0].with_stacked(|items| {
  1039. assert_eq!(items.len(), 10);
  1040. }).unwrap();
  1041. }
  1042. #[async_std::test]
  1043. async fn test_withdraw_individual_item_in_full_inventory() {
  1044. let mut entity_gateway = InMemoryGateway::default();
  1045. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1046. let mut bank = Vec::new();
  1047. bank.push(entity_gateway.create_item(
  1048. item::NewItemEntity {
  1049. item: item::ItemDetail::Weapon(
  1050. item::weapon::Weapon {
  1051. weapon: item::weapon::WeaponType::Vulcan,
  1052. grind: 0,
  1053. special: None,
  1054. attrs: [None, None, None],
  1055. tekked: true,
  1056. }
  1057. ),
  1058. }).await.unwrap());
  1059. let mut inventory = Vec::new();
  1060. for _ in 0..30usize {
  1061. inventory.push(entity_gateway.create_item(
  1062. item::NewItemEntity {
  1063. item: item::ItemDetail::Weapon(
  1064. item::weapon::Weapon {
  1065. weapon: item::weapon::WeaponType::Vulcan,
  1066. grind: 0,
  1067. special: None,
  1068. attrs: [None, None, None],
  1069. tekked: true,
  1070. }
  1071. ),
  1072. }).await.unwrap());
  1073. }
  1074. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap();
  1075. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), item::BankName("".into())).await.unwrap();
  1076. let mut ship = Box::new(ShipServerState::builder()
  1077. .gateway(entity_gateway.clone())
  1078. .build());
  1079. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1080. join_lobby(&mut ship, ClientId(1)).await;
  1081. create_room(&mut ship, ClientId(1), "room", "").await;
  1082. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1083. client: 0,
  1084. target: 0,
  1085. unknown: 0,
  1086. })))).await.unwrap().for_each(drop);
  1087. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1088. client: 0,
  1089. target: 0,
  1090. item_id: 0x20000,
  1091. action: 1,
  1092. item_amount: 0,
  1093. meseta_amount: 0,
  1094. unknown: 0,
  1095. })))).await;
  1096. assert!(packets.is_err());
  1097. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  1098. assert_eq!(bank_items.items.len(), 1);
  1099. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1100. assert_eq!(inventory_items.items.len(), 30);
  1101. }
  1102. #[async_std::test]
  1103. async fn test_withdraw_stacked_item_in_full_inventory() {
  1104. let mut entity_gateway = InMemoryGateway::default();
  1105. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1106. let mut monomates = Vec::new();
  1107. for _ in 0..2usize {
  1108. monomates.push(entity_gateway.create_item(
  1109. item::NewItemEntity {
  1110. item: item::ItemDetail::Tool(
  1111. item::tool::Tool {
  1112. tool: item::tool::ToolType::Monomate,
  1113. }
  1114. ),
  1115. }).await.unwrap());
  1116. }
  1117. let mut inventory = Vec::new();
  1118. for _ in 0..30usize {
  1119. inventory.push(entity_gateway.create_item(
  1120. item::NewItemEntity {
  1121. item: item::ItemDetail::Weapon(
  1122. item::weapon::Weapon {
  1123. weapon: item::weapon::WeaponType::Vulcan,
  1124. grind: 0,
  1125. special: None,
  1126. attrs: [None, None, None],
  1127. tekked: true,
  1128. }
  1129. ),
  1130. }).await.unwrap());
  1131. }
  1132. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap();
  1133. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), item::BankName("".into())).await.unwrap();
  1134. let mut ship = Box::new(ShipServerState::builder()
  1135. .gateway(entity_gateway.clone())
  1136. .build());
  1137. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1138. join_lobby(&mut ship, ClientId(1)).await;
  1139. create_room(&mut ship, ClientId(1), "room", "").await;
  1140. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1141. client: 0,
  1142. target: 0,
  1143. unknown: 0,
  1144. })))).await.unwrap().for_each(drop);
  1145. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1146. client: 0,
  1147. target: 0,
  1148. item_id: 0x20000,
  1149. action: 1,
  1150. item_amount: 2,
  1151. meseta_amount: 0,
  1152. unknown: 0,
  1153. })))).await;
  1154. assert!(packets.is_err());
  1155. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  1156. assert_eq!(bank_items.items.len(), 1);
  1157. bank_items.items[0].with_stacked(|items| {
  1158. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  1159. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  1160. }).unwrap();
  1161. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1162. assert_eq!(inventory_items.items.len(), 30);
  1163. }
  1164. #[async_std::test]
  1165. async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() {
  1166. let mut entity_gateway = InMemoryGateway::default();
  1167. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1168. let mut bank_item = Vec::new();
  1169. for _ in 0..2usize {
  1170. bank_item.push(entity_gateway.create_item(
  1171. item::NewItemEntity {
  1172. item: item::ItemDetail::Tool(
  1173. item::tool::Tool {
  1174. tool: item::tool::ToolType::Monomate,
  1175. }
  1176. ),
  1177. }).await.unwrap());
  1178. }
  1179. entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_item]), item::BankName("".into())).await.unwrap();
  1180. let mut items = Vec::new();
  1181. for i in 0..29usize {
  1182. items.push(entity_gateway.create_item(
  1183. item::NewItemEntity {
  1184. item: item::ItemDetail::Weapon(
  1185. item::weapon::Weapon {
  1186. weapon: item::weapon::WeaponType::Vulcan,
  1187. grind: 0,
  1188. special: None,
  1189. attrs: [None, None, None],
  1190. tekked: true,
  1191. }
  1192. ),
  1193. }).await.unwrap().into());
  1194. }
  1195. let mut item29 = Vec::new();
  1196. for _ in 0..2usize {
  1197. item29.push(entity_gateway.create_item(
  1198. item::NewItemEntity {
  1199. item: item::ItemDetail::Tool(
  1200. item::tool::Tool {
  1201. tool: item::tool::ToolType::Monomate,
  1202. }
  1203. ),
  1204. }).await.unwrap());
  1205. }
  1206. items.push(item::InventoryItemEntity::Stacked(item29));
  1207. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(items)).await.unwrap();
  1208. let mut ship = Box::new(ShipServerState::builder()
  1209. .gateway(entity_gateway.clone())
  1210. .build());
  1211. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1212. join_lobby(&mut ship, ClientId(1)).await;
  1213. create_room(&mut ship, ClientId(1), "room", "").await;
  1214. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1215. client: 0,
  1216. target: 0,
  1217. unknown: 0,
  1218. })))).await.unwrap().for_each(drop);
  1219. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1220. client: 0,
  1221. target: 0,
  1222. item_id: 0x20000,
  1223. action: 1,
  1224. item_amount: 2,
  1225. meseta_amount: 0,
  1226. unknown: 0,
  1227. })))).await.unwrap().for_each(drop);
  1228. let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap();
  1229. assert!(bank_items.items.len() == 0);
  1230. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  1231. assert!(inventory_items.items.len() == 30);
  1232. match &inventory_items.items[29] {
  1233. item::InventoryItemEntity::Stacked(items) => {
  1234. assert_eq!(items.len(), 4);
  1235. },
  1236. _ => panic!(),
  1237. }
  1238. }
  1239. #[async_std::test]
  1240. async fn test_withdraw_meseta() {
  1241. let mut entity_gateway = InMemoryGateway::default();
  1242. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1243. entity_gateway.set_bank_meseta(&char1.id, item::BankName("".into()), item::Meseta(300)).await.unwrap();
  1244. let mut ship = Box::new(ShipServerState::builder()
  1245. .gateway(entity_gateway.clone())
  1246. .build());
  1247. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1248. join_lobby(&mut ship, ClientId(1)).await;
  1249. create_room(&mut ship, ClientId(1), "room", "").await;
  1250. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1251. client: 0,
  1252. target: 0,
  1253. unknown: 0,
  1254. })))).await.unwrap().for_each(drop);
  1255. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1256. client: 0,
  1257. target: 0,
  1258. item_id: 0xFFFFFFFF,
  1259. action: 1,
  1260. item_amount: 0,
  1261. meseta_amount: 23,
  1262. unknown: 0,
  1263. })))).await.unwrap().for_each(drop);
  1264. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  1265. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, item::BankName("".into())).await.unwrap();
  1266. assert!(c1_meseta.0 == 23);
  1267. assert!(c1_bank_meseta.0 == 277);
  1268. }
  1269. #[async_std::test]
  1270. async fn test_withdraw_too_much_meseta() {
  1271. let mut entity_gateway = InMemoryGateway::default();
  1272. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1273. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999980)).await.unwrap();
  1274. entity_gateway.set_bank_meseta(&char1.id, item::BankName("".into()), item::Meseta(300)).await.unwrap();
  1275. let mut ship = Box::new(ShipServerState::builder()
  1276. .gateway(entity_gateway.clone())
  1277. .build());
  1278. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1279. join_lobby(&mut ship, ClientId(1)).await;
  1280. create_room(&mut ship, ClientId(1), "room", "").await;
  1281. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1282. client: 0,
  1283. target: 0,
  1284. unknown: 0,
  1285. })))).await.unwrap().for_each(drop);
  1286. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1287. client: 0,
  1288. target: 0,
  1289. item_id: 0xFFFFFFFF,
  1290. action: 1,
  1291. item_amount: 0,
  1292. meseta_amount: 23,
  1293. unknown: 0,
  1294. })))).await.unwrap().for_each(drop);
  1295. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  1296. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, item::BankName("".into())).await.unwrap();
  1297. assert!(c1_meseta.0 == 999980);
  1298. assert!(c1_bank_meseta.0 == 300);
  1299. }
  1300. #[async_std::test]
  1301. async fn test_withdraw_meseta_inventory_is_maxed() {
  1302. let mut entity_gateway = InMemoryGateway::default();
  1303. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  1304. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  1305. entity_gateway.set_bank_meseta(&char1.id, item::BankName("".into()), item::Meseta(300)).await.unwrap();
  1306. let mut ship = Box::new(ShipServerState::builder()
  1307. .gateway(entity_gateway.clone())
  1308. .build());
  1309. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  1310. join_lobby(&mut ship, ClientId(1)).await;
  1311. create_room(&mut ship, ClientId(1), "room", "").await;
  1312. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
  1313. client: 0,
  1314. target: 0,
  1315. unknown: 0,
  1316. })))).await.unwrap().for_each(drop);
  1317. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
  1318. client: 0,
  1319. target: 0,
  1320. item_id: 0xFFFFFFFF,
  1321. action: 1,
  1322. item_amount: 0,
  1323. meseta_amount: 23,
  1324. unknown: 0,
  1325. })))).await.unwrap().for_each(drop);
  1326. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  1327. let c1_bank_meseta = entity_gateway.get_bank_meseta(&char1.id, item::BankName("".into())).await.unwrap();
  1328. assert!(c1_meseta.0 == 999999);
  1329. assert!(c1_bank_meseta.0 == 300);
  1330. }