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.

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