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.

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