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.

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