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.

808 lines
29 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
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
4 years ago
  1. use elseware::common::serverstate::{ClientId, ServerState};
  2. use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
  3. use elseware::entity::item;
  4. use elseware::ship::ship::{ShipServerState, RecvShipPacket};
  5. use libpso::packet::ship::*;
  6. use libpso::packet::messages::*;
  7. #[path = "common.rs"]
  8. mod common;
  9. use common::*;
  10. #[async_std::test]
  11. async fn test_pick_up_individual_item() {
  12. let mut entity_gateway = InMemoryGateway::default();
  13. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  14. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  15. let mut p1_inv = Vec::new();
  16. p1_inv.push(entity_gateway.create_item(
  17. item::NewItemEntity {
  18. item: item::ItemDetail::Weapon(
  19. item::weapon::Weapon {
  20. weapon: item::weapon::WeaponType::Handgun,
  21. grind: 0,
  22. special: None,
  23. attrs: [None, None, None],
  24. tekked: true,
  25. }
  26. ),
  27. location: item::ItemLocation::Inventory {
  28. character_id: char1.id,
  29. }
  30. }).await.unwrap());
  31. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  32. entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::<item::InventoryItemEntity>::new())).await.unwrap();
  33. let mut ship = Box::new(ShipServerState::builder()
  34. .gateway(entity_gateway.clone())
  35. .build());
  36. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  37. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  38. join_lobby(&mut ship, ClientId(1)).await;
  39. join_lobby(&mut ship, ClientId(2)).await;
  40. create_room(&mut ship, ClientId(1), "room", "").await;
  41. join_room(&mut ship, ClientId(2), 0).await;
  42. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  43. assert_eq!(p1_items.items.len(), 1);
  44. let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
  45. assert_eq!(p2_items.items.len(), 0);
  46. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  47. client: 0,
  48. target: 0,
  49. unknown1: 0,
  50. map_area: 0,
  51. item_id: 0x10000,
  52. x: 0.0,
  53. y: 0.0,
  54. z: 0.0,
  55. })))).await.unwrap().for_each(drop);
  56. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  57. assert_eq!(p1_items.items.len(), 0);
  58. let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
  59. assert_eq!(p2_items.items.len(), 0);
  60. ship.handle(ClientId(2), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  61. client: 0,
  62. target: 0,
  63. item_id: 0x10000,
  64. map_area: 0,
  65. unknown: [0; 3]
  66. })))).await.unwrap().for_each(drop);
  67. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  68. assert_eq!(p1_items.items.len(), 0);
  69. let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
  70. assert_eq!(p2_items.items.len(), 1);
  71. }
  72. #[async_std::test]
  73. async fn test_pick_up_item_stack_of_items_already_in_inventory() {
  74. let mut entity_gateway = InMemoryGateway::default();
  75. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  76. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  77. let mut p1_monomate = Vec::new();
  78. p1_monomate.push(entity_gateway.create_item(
  79. item::NewItemEntity {
  80. item: item::ItemDetail::Tool(
  81. item::tool::Tool {
  82. tool: item::tool::ToolType::Monomate
  83. }
  84. ),
  85. location: item::ItemLocation::Inventory {
  86. character_id: char1.id,
  87. }
  88. }).await.unwrap());
  89. let mut p2_items = Vec::new();
  90. for (slot, tool) in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter().enumerate() {
  91. let mut item = Vec::new();
  92. for _ in 0..5usize {
  93. item.push(entity_gateway.create_item(
  94. item::NewItemEntity {
  95. item: item::ItemDetail::Tool(
  96. item::tool::Tool {
  97. tool: tool
  98. }
  99. ),
  100. location: item::ItemLocation::Inventory {
  101. character_id: char2.id,
  102. }
  103. }).await.unwrap());
  104. }
  105. p2_items.push(item);
  106. }
  107. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_monomate])).await.unwrap();
  108. entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_items)).await.unwrap();
  109. let mut ship = Box::new(ShipServerState::builder()
  110. .gateway(entity_gateway.clone())
  111. .build());
  112. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  113. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  114. join_lobby(&mut ship, ClientId(1)).await;
  115. join_lobby(&mut ship, ClientId(2)).await;
  116. create_room(&mut ship, ClientId(1), "room", "").await;
  117. join_room(&mut ship, ClientId(2), 0).await;
  118. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  119. client: 0,
  120. target: 0,
  121. unknown1: 0,
  122. map_area: 0,
  123. item_id: 0x210000,
  124. x: 0.0,
  125. y: 0.0,
  126. z: 0.0,
  127. })))).await.unwrap().for_each(drop);
  128. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  129. client: 0,
  130. target: 0,
  131. item_id: 0x210000,
  132. map_area: 0,
  133. unknown: [0; 3]
  134. })))).await.unwrap().for_each(drop);
  135. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  136. assert_eq!(inventory_items.items.len(), 1);
  137. inventory_items.items[0].with_stacked(|items| {
  138. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  139. vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5), item::ItemEntityId(6)]);
  140. assert!(items.iter().all(|item| item.item.item_type() == item::ItemType::Tool(item::tool::ToolType::Monomate)));
  141. }).unwrap();
  142. }
  143. #[async_std::test]
  144. async fn test_pick_up_item_stack_of_items_not_already_held() {
  145. let mut entity_gateway = InMemoryGateway::default();
  146. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  147. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  148. let mut p2_monomate = Vec::new();
  149. p2_monomate.push(entity_gateway.create_item(
  150. item::NewItemEntity {
  151. item: item::ItemDetail::Tool(
  152. item::tool::Tool {
  153. tool: item::tool::ToolType::Monomate
  154. }
  155. ),
  156. location: item::ItemLocation::Inventory {
  157. character_id: char2.id,
  158. }
  159. }).await.unwrap());
  160. entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomate])).await.unwrap();
  161. let mut ship = Box::new(ShipServerState::builder()
  162. .gateway(entity_gateway.clone())
  163. .build());
  164. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  165. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  166. join_lobby(&mut ship, ClientId(1)).await;
  167. join_lobby(&mut ship, ClientId(2)).await;
  168. create_room(&mut ship, ClientId(1), "room", "").await;
  169. join_room(&mut ship, ClientId(2), 0).await;
  170. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  171. client: 0,
  172. target: 0,
  173. unknown1: 0,
  174. map_area: 0,
  175. item_id: 0x210000,
  176. x: 0.0,
  177. y: 0.0,
  178. z: 0.0,
  179. })))).await.unwrap().for_each(drop);
  180. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  181. client: 0,
  182. target: 0,
  183. item_id: 0x210000,
  184. map_area: 0,
  185. unknown: [0; 3]
  186. })))).await.unwrap().for_each(drop);
  187. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  188. assert_eq!(inventory_items.items.len(), 1);
  189. inventory_items.items[0].with_stacked(|items| {
  190. assert_eq!(items.len(), 1);
  191. assert_eq!(items[0].id, item::ItemEntityId(1));
  192. assert_eq!(items[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Monomate));
  193. }).unwrap();
  194. }
  195. #[async_std::test]
  196. async fn test_pick_up_meseta_when_inventory_full() {
  197. let mut entity_gateway = InMemoryGateway::default();
  198. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  199. let (user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  200. let mut p1_items = Vec::new();
  201. for _ in 0..30usize {
  202. p1_items.push(entity_gateway.create_item(
  203. item::NewItemEntity {
  204. item: item::ItemDetail::Weapon(
  205. item::weapon::Weapon {
  206. weapon: item::weapon::WeaponType::Saber,
  207. grind: 0,
  208. special: None,
  209. attrs: [None, None, None],
  210. tekked: true,
  211. }
  212. ),
  213. location: item::ItemLocation::Inventory {
  214. character_id: char1.id,
  215. }
  216. }).await.unwrap());
  217. }
  218. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap();
  219. char2.meseta = 300;
  220. entity_gateway.save_character(&char2).await.unwrap();
  221. let mut ship = Box::new(ShipServerState::builder()
  222. .gateway(entity_gateway.clone())
  223. .build());
  224. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  225. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  226. join_lobby(&mut ship, ClientId(1)).await;
  227. join_lobby(&mut ship, ClientId(2)).await;
  228. create_room(&mut ship, ClientId(1), "room", "").await;
  229. join_room(&mut ship, ClientId(2), 0).await;
  230. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  231. client: 0,
  232. target: 0,
  233. item_id: 0xFFFFFFFF,
  234. map_area: 0,
  235. room: 0,
  236. x: 0.0,
  237. z: 0.0,
  238. })))).await.unwrap().for_each(drop);
  239. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
  240. client: 0,
  241. target: 0,
  242. item_id: 0xFFFFFFFF,
  243. amount: 23,
  244. })))).await.unwrap().for_each(drop);
  245. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  246. client: 0,
  247. target: 0,
  248. item_id: 0x00810001,
  249. map_area: 0,
  250. unknown: [0; 3]
  251. })))).await.unwrap().for_each(drop);
  252. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  253. assert_eq!(inventory_items.items.len(), 30);
  254. let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  255. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  256. let characters2 = entity_gateway.get_characters_by_user(&user2).await.unwrap();
  257. let c2 = characters2.get(0).as_ref().unwrap().as_ref().unwrap();
  258. assert!(c1.meseta == 23);
  259. assert!(c2.meseta == 277);
  260. }
  261. #[async_std::test]
  262. async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() {
  263. let mut entity_gateway = InMemoryGateway::default();
  264. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  265. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  266. let mut p1_inv = Vec::new();
  267. for slot in 0..29usize {
  268. p1_inv.push(entity_gateway.create_item(
  269. item::NewItemEntity {
  270. item: item::ItemDetail::Weapon(
  271. item::weapon::Weapon {
  272. weapon: item::weapon::WeaponType::Saber,
  273. grind: 0,
  274. special: None,
  275. attrs: [None, None, None],
  276. tekked: true,
  277. }
  278. ),
  279. location: item::ItemLocation::Inventory {
  280. character_id: char1.id,
  281. }
  282. }).await.unwrap().into());
  283. }
  284. p1_inv.push(item::InventoryItemEntity::Stacked(vec![entity_gateway.create_item(
  285. item::NewItemEntity {
  286. item: item::ItemDetail::Tool(
  287. item::tool::Tool {
  288. tool: item::tool::ToolType::Monomate,
  289. }
  290. ),
  291. location: item::ItemLocation::Inventory {
  292. character_id: char1.id,
  293. }
  294. }).await.unwrap()]));
  295. let mut p2_monomates = Vec::new();
  296. p2_monomates.push(entity_gateway.create_item(
  297. item::NewItemEntity {
  298. item: item::ItemDetail::Tool(
  299. item::tool::Tool {
  300. tool: item::tool::ToolType::Monomate,
  301. }
  302. ),
  303. location: item::ItemLocation::Inventory {
  304. character_id: char2.id,
  305. }
  306. }).await.unwrap());
  307. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  308. entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomates])).await.unwrap();
  309. let mut ship = Box::new(ShipServerState::builder()
  310. .gateway(entity_gateway.clone())
  311. .build());
  312. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  313. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  314. join_lobby(&mut ship, ClientId(1)).await;
  315. join_lobby(&mut ship, ClientId(2)).await;
  316. create_room(&mut ship, ClientId(1), "room", "").await;
  317. join_room(&mut ship, ClientId(2), 0).await;
  318. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  319. client: 0,
  320. target: 0,
  321. unknown1: 0,
  322. map_area: 0,
  323. item_id: 0x210000,
  324. x: 0.0,
  325. y: 0.0,
  326. z: 0.0,
  327. })))).await.unwrap().for_each(drop);
  328. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  329. client: 0,
  330. target: 0,
  331. item_id: 0x210000,
  332. map_area: 0,
  333. unknown: [0; 3]
  334. })))).await.unwrap().for_each(drop);
  335. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  336. assert_eq!(inventory_items.items.len(), 30);
  337. inventory_items.items[29].with_stacked(|items| {
  338. assert_eq!(items.len(), 2);
  339. }).unwrap();
  340. }
  341. #[async_std::test]
  342. async fn test_can_not_pick_up_item_when_inventory_full() {
  343. let mut entity_gateway = InMemoryGateway::default();
  344. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  345. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  346. let mut p1_inv = Vec::new();
  347. for slot in 0..30usize {
  348. p1_inv.push(entity_gateway.create_item(
  349. item::NewItemEntity {
  350. item: item::ItemDetail::Weapon(
  351. item::weapon::Weapon {
  352. weapon: item::weapon::WeaponType::Saber,
  353. grind: 0,
  354. special: None,
  355. attrs: [None, None, None],
  356. tekked: true,
  357. }
  358. ),
  359. location: item::ItemLocation::Inventory {
  360. character_id: char1.id,
  361. }
  362. }).await.unwrap());
  363. }
  364. let mut p2_inv = Vec::new();
  365. p2_inv.push(entity_gateway.create_item(
  366. item::NewItemEntity {
  367. item: item::ItemDetail::Weapon(
  368. item::weapon::Weapon {
  369. weapon: item::weapon::WeaponType::Handgun,
  370. grind: 0,
  371. special: None,
  372. attrs: [None, None, None],
  373. tekked: true,
  374. }
  375. ),
  376. location: item::ItemLocation::Inventory {
  377. character_id: char2.id,
  378. }
  379. }).await.unwrap());
  380. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  381. entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap();
  382. let mut ship = Box::new(ShipServerState::builder()
  383. .gateway(entity_gateway.clone())
  384. .build());
  385. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  386. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  387. join_lobby(&mut ship, ClientId(1)).await;
  388. join_lobby(&mut ship, ClientId(2)).await;
  389. create_room(&mut ship, ClientId(1), "room", "").await;
  390. join_room(&mut ship, ClientId(2), 0).await;
  391. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  392. client: 0,
  393. target: 0,
  394. unknown1: 0,
  395. map_area: 0,
  396. item_id: 0x210000,
  397. x: 0.0,
  398. y: 0.0,
  399. z: 0.0,
  400. })))).await.unwrap().for_each(drop);
  401. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  402. client: 0,
  403. target: 0,
  404. item_id: 0x210000,
  405. map_area: 0,
  406. unknown: [0; 3]
  407. })))).await.unwrap().for_each(drop);
  408. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  409. assert_eq!(p1_items.items.len(), 30);
  410. let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
  411. assert_eq!(p2_items.items.len(), 0);
  412. ship.handle(ClientId(2), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  413. client: 0,
  414. target: 0,
  415. item_id: 0x210000,
  416. map_area: 0,
  417. unknown: [0; 3]
  418. })))).await.unwrap().for_each(drop);
  419. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  420. assert_eq!(p1_items.items.len(), 30);
  421. let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
  422. assert_eq!(p2_items.items.len(), 1);
  423. }
  424. #[async_std::test]
  425. async fn test_can_not_drop_more_meseta_than_is_held() {
  426. let mut entity_gateway = InMemoryGateway::default();
  427. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  428. char1.meseta = 300;
  429. entity_gateway.save_character(&char1).await.unwrap();
  430. let mut ship = Box::new(ShipServerState::builder()
  431. .gateway(entity_gateway.clone())
  432. .build());
  433. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  434. join_lobby(&mut ship, ClientId(1)).await;
  435. create_room(&mut ship, ClientId(1), "room", "").await;
  436. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  437. client: 0,
  438. target: 0,
  439. item_id: 0xFFFFFFFF,
  440. map_area: 0,
  441. room: 0,
  442. x: 0.0,
  443. z: 0.0,
  444. })))).await.unwrap().for_each(drop);
  445. let split_attempt = ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
  446. client: 0,
  447. target: 0,
  448. item_id: 0xFFFFFFFF,
  449. amount: 301,
  450. })))).await;
  451. assert!(split_attempt.is_err());
  452. let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  453. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  454. assert!(c1.meseta == 300);
  455. }
  456. #[async_std::test]
  457. async fn test_pick_up_stack_that_would_exceed_stack_limit() {
  458. let mut entity_gateway = InMemoryGateway::default();
  459. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  460. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  461. let mut p1_monomates = Vec::new();
  462. for _ in 0..6usize {
  463. p1_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 p2_monomates = Vec::new();
  476. for _ in 0..6usize {
  477. p2_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::Inventory {
  485. character_id: char2.id,
  486. }
  487. }).await.unwrap());
  488. }
  489. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_monomates])).await.unwrap();
  490. entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomates])).await.unwrap();
  491. let mut ship = Box::new(ShipServerState::builder()
  492. .gateway(entity_gateway.clone())
  493. .build());
  494. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  495. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  496. join_lobby(&mut ship, ClientId(1)).await;
  497. join_lobby(&mut ship, ClientId(2)).await;
  498. create_room(&mut ship, ClientId(1), "room", "").await;
  499. join_room(&mut ship, ClientId(2), 0).await;
  500. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  501. client: 0,
  502. target: 0,
  503. unknown1: 0,
  504. map_area: 0,
  505. item_id: 0x210000,
  506. x: 0.0,
  507. y: 0.0,
  508. z: 0.0,
  509. })))).await.unwrap().for_each(drop);
  510. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  511. client: 0,
  512. target: 0,
  513. item_id: 0x210000,
  514. map_area: 0,
  515. unknown: [0; 3]
  516. })))).await.unwrap().collect::<Vec<_>>();
  517. assert!(packets.len() == 0);
  518. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  519. assert_eq!(p1_items.items.len(), 1);
  520. p1_items.items[0].with_stacked(|items| {
  521. assert_eq!(items.len(), 6);
  522. }).unwrap();
  523. let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
  524. assert_eq!(p2_items.items.len(), 0);
  525. }
  526. #[async_std::test]
  527. async fn test_can_not_pick_up_meseta_when_full() {
  528. let mut entity_gateway = InMemoryGateway::default();
  529. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  530. let (user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  531. char1.meseta = 999999;
  532. entity_gateway.save_character(&char1).await.unwrap();
  533. char2.meseta = 300;
  534. entity_gateway.save_character(&char2).await.unwrap();
  535. let mut ship = Box::new(ShipServerState::builder()
  536. .gateway(entity_gateway.clone())
  537. .build());
  538. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  539. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  540. join_lobby(&mut ship, ClientId(1)).await;
  541. join_lobby(&mut ship, ClientId(2)).await;
  542. create_room(&mut ship, ClientId(1), "room", "").await;
  543. join_room(&mut ship, ClientId(2), 0).await;
  544. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  545. client: 0,
  546. target: 0,
  547. item_id: 0xFFFFFFFF,
  548. map_area: 0,
  549. room: 0,
  550. x: 0.0,
  551. z: 0.0,
  552. })))).await.unwrap().for_each(drop);
  553. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
  554. client: 0,
  555. target: 0,
  556. item_id: 0xFFFFFFFF,
  557. amount: 23,
  558. })))).await.unwrap().for_each(drop);
  559. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  560. client: 0,
  561. target: 0,
  562. item_id: 0x00810001,
  563. map_area: 0,
  564. unknown: [0; 3]
  565. })))).await.unwrap().collect::<Vec<_>>();
  566. assert!(packets.len() == 0);
  567. let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  568. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  569. let characters2 = entity_gateway.get_characters_by_user(&user2).await.unwrap();
  570. let c2 = characters2.get(0).as_ref().unwrap().as_ref().unwrap();
  571. assert!(c1.meseta == 999999);
  572. assert!(c2.meseta == 277);
  573. }
  574. #[async_std::test]
  575. async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() {
  576. let mut entity_gateway = InMemoryGateway::default();
  577. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  578. let (user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  579. char1.meseta = 999998;
  580. entity_gateway.save_character(&char1).await.unwrap();
  581. char2.meseta = 300;
  582. entity_gateway.save_character(&char2).await.unwrap();
  583. let mut ship = Box::new(ShipServerState::builder()
  584. .gateway(entity_gateway.clone())
  585. .build());
  586. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  587. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  588. join_lobby(&mut ship, ClientId(1)).await;
  589. join_lobby(&mut ship, ClientId(2)).await;
  590. create_room(&mut ship, ClientId(1), "room", "").await;
  591. join_room(&mut ship, ClientId(2), 0).await;
  592. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  593. client: 0,
  594. target: 0,
  595. item_id: 0xFFFFFFFF,
  596. map_area: 0,
  597. room: 0,
  598. x: 0.0,
  599. z: 0.0,
  600. })))).await.unwrap().for_each(drop);
  601. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
  602. client: 0,
  603. target: 0,
  604. item_id: 0xFFFFFFFF,
  605. amount: 23,
  606. })))).await.unwrap().for_each(drop);
  607. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  608. client: 0,
  609. target: 0,
  610. item_id: 0x00810001,
  611. map_area: 0,
  612. unknown: [0; 3]
  613. })))).await.unwrap().for_each(drop);
  614. let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  615. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  616. let characters2 = entity_gateway.get_characters_by_user(&user2).await.unwrap();
  617. let c2 = characters2.get(0).as_ref().unwrap().as_ref().unwrap();
  618. assert!(c1.meseta == 999999);
  619. assert!(c2.meseta == 277);
  620. }
  621. #[async_std::test]
  622. async fn test_player_drops_partial_stack_and_other_player_picks_it_up() {
  623. let mut entity_gateway = InMemoryGateway::default();
  624. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  625. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  626. let mut monomates = Vec::new();
  627. for _ in 0..5usize {
  628. monomates.push(entity_gateway.create_item(
  629. item::NewItemEntity {
  630. item: item::ItemDetail::Tool(
  631. item::tool::Tool {
  632. tool: item::tool::ToolType::Monomate,
  633. }
  634. ),
  635. location: item::ItemLocation::Inventory {
  636. character_id: char1.id,
  637. }
  638. }).await.unwrap());
  639. }
  640. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap();
  641. let mut ship = Box::new(ShipServerState::builder()
  642. .gateway(entity_gateway.clone())
  643. .build());
  644. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  645. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  646. join_lobby(&mut ship, ClientId(1)).await;
  647. join_lobby(&mut ship, ClientId(2)).await;
  648. create_room(&mut ship, ClientId(1), "room", "").await;
  649. join_room(&mut ship, ClientId(2), 0).await;
  650. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  651. client: 0,
  652. target: 0,
  653. item_id: 0x10000,
  654. map_area: 0,
  655. room: 0,
  656. x: 0.0,
  657. z: 0.0,
  658. })))).await.unwrap().for_each(drop);
  659. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
  660. client: 0,
  661. target: 0,
  662. item_id: 0x10000,
  663. amount: 2,
  664. })))).await.unwrap().for_each(drop);
  665. ship.handle(ClientId(2), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  666. client: 0,
  667. target: 0,
  668. item_id: 0x00810001,
  669. map_area: 0,
  670. unknown: [0; 3]
  671. })))).await.unwrap().for_each(drop);
  672. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  673. assert_eq!(inventory_items.items.len(), 1);
  674. inventory_items.items[0].with_stacked(|items| {
  675. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  676. vec![item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5)]);
  677. }).unwrap();
  678. let inventory_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
  679. assert_eq!(inventory_items.items.len(), 1);
  680. inventory_items.items[0].with_stacked(|items| {
  681. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  682. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  683. }).unwrap();
  684. }