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.

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