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.

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