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.

684 lines
24 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. use std::time::SystemTime;
  2. use elseware::common::serverstate::{ClientId, ServerState};
  3. use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
  4. use elseware::entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity};
  5. use elseware::entity::character::{CharacterEntity, NewCharacterEntity};
  6. //use elseware::entity::item::{NewItemEntity, ItemDetail, ItemLocation};
  7. use elseware::entity::item;
  8. use elseware::ship::ship::{ShipServerState, RecvShipPacket};
  9. use elseware::ship::items::{ClientItemId, ActiveItemEntityId, HeldItemType, FloorItemType};
  10. use libpso::packet::ship::*;
  11. use libpso::packet::messages::*;
  12. use libpso::packet::login::{Login, Session};
  13. use libpso::{utf8_to_array, utf8_to_utf16_array};
  14. #[path = "common.rs"]
  15. mod common;
  16. use common::*;
  17. #[async_std::test]
  18. async fn test_pick_up_item_stack_of_items_already_in_inventory() {
  19. let mut entity_gateway = InMemoryGateway::new();
  20. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  21. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  22. entity_gateway.create_item(
  23. item::NewItemEntity {
  24. item: item::ItemDetail::Tool(
  25. item::tool::Tool {
  26. tool: item::tool::ToolType::Monomate
  27. }
  28. ),
  29. location: item::ItemLocation::Inventory {
  30. character_id: char1.id,
  31. slot: 0,
  32. equipped: false,
  33. }
  34. }).await;
  35. for (slot, tool) in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter().enumerate() {
  36. for _ in 0..5 {
  37. entity_gateway.create_item(
  38. item::NewItemEntity {
  39. item: item::ItemDetail::Tool(
  40. item::tool::Tool {
  41. tool: tool
  42. }
  43. ),
  44. location: item::ItemLocation::Inventory {
  45. character_id: char2.id,
  46. slot: slot,
  47. equipped: false,
  48. }
  49. }).await;
  50. }
  51. }
  52. let mut ship = ShipServerState::new(entity_gateway.clone());
  53. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  54. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  55. join_lobby(&mut ship, ClientId(1)).await;
  56. join_lobby(&mut ship, ClientId(2)).await;
  57. create_room(&mut ship, ClientId(1), "room", "").await;
  58. join_room(&mut ship, ClientId(2), 0).await;
  59. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  60. client: 0,
  61. target: 0,
  62. unknown1: 0,
  63. area: 0,
  64. item_id: 0x210000,
  65. x: 0.0,
  66. y: 0.0,
  67. z: 0.0,
  68. })))).await.unwrap().for_each(drop);
  69. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  70. client: 0,
  71. target: 0,
  72. item_id: 0x210000,
  73. area: 0,
  74. unknown: [0; 3]
  75. })))).await.unwrap().for_each(drop);
  76. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  77. assert!(p1_inventory.count() == 1);
  78. let inventory_item = p1_inventory.slot(0).unwrap();
  79. assert!(inventory_item.entity_id == ActiveItemEntityId::Stacked(vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5), item::ItemEntityId(6)]));
  80. assert!(inventory_item.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 6));
  81. }
  82. #[async_std::test]
  83. async fn test_pick_up_item_stack_of_items_not_already_held() {
  84. let mut entity_gateway = InMemoryGateway::new();
  85. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  86. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  87. entity_gateway.create_item(
  88. item::NewItemEntity {
  89. item: item::ItemDetail::Tool(
  90. item::tool::Tool {
  91. tool: item::tool::ToolType::Monomate
  92. }
  93. ),
  94. location: item::ItemLocation::Inventory {
  95. character_id: char2.id,
  96. slot: 0,
  97. equipped: false,
  98. }
  99. }).await;
  100. let mut ship = ShipServerState::new(entity_gateway.clone());
  101. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  102. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  103. join_lobby(&mut ship, ClientId(1)).await;
  104. join_lobby(&mut ship, ClientId(2)).await;
  105. create_room(&mut ship, ClientId(1), "room", "").await;
  106. join_room(&mut ship, ClientId(2), 0).await;
  107. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  108. client: 0,
  109. target: 0,
  110. unknown1: 0,
  111. area: 0,
  112. item_id: 0x210000,
  113. x: 0.0,
  114. y: 0.0,
  115. z: 0.0,
  116. })))).await.unwrap().for_each(drop);
  117. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  118. client: 0,
  119. target: 0,
  120. item_id: 0x210000,
  121. area: 0,
  122. unknown: [0; 3]
  123. })))).await.unwrap().for_each(drop);
  124. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  125. assert!(p1_inventory.count() == 1);
  126. let inventory_item = p1_inventory.slot(0).unwrap();
  127. assert!(inventory_item.entity_id == ActiveItemEntityId::Stacked(vec![item::ItemEntityId(1)]));
  128. assert!(inventory_item.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 1));
  129. }
  130. #[async_std::test]
  131. async fn test_pick_up_meseta_when_inventory_full() {
  132. let mut entity_gateway = InMemoryGateway::new();
  133. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  134. let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  135. for slot in 0..30 {
  136. entity_gateway.create_item(
  137. item::NewItemEntity {
  138. item: item::ItemDetail::Weapon(
  139. item::weapon::Weapon {
  140. weapon: item::weapon::WeaponType::Saber,
  141. grind: 0,
  142. special: None,
  143. attrs: [None, None, None],
  144. tekked: true,
  145. }
  146. ),
  147. location: item::ItemLocation::Inventory {
  148. character_id: char1.id,
  149. slot: slot,
  150. equipped: false,
  151. }
  152. }).await;
  153. }
  154. char2.meseta = 300;
  155. entity_gateway.save_character(&char2).await;
  156. let mut ship = ShipServerState::new(entity_gateway.clone());
  157. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  158. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  159. join_lobby(&mut ship, ClientId(1)).await;
  160. join_lobby(&mut ship, ClientId(2)).await;
  161. create_room(&mut ship, ClientId(1), "room", "").await;
  162. join_room(&mut ship, ClientId(2), 0).await;
  163. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  164. client: 0,
  165. target: 0,
  166. item_id: 0xFFFFFFFF,
  167. map_area: 0,
  168. x: 0.0,
  169. z: 0.0,
  170. })))).await.unwrap().for_each(drop);
  171. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  172. client: 0,
  173. target: 0,
  174. item_id: 0xFFFFFFFF,
  175. amount: 23,
  176. })))).await.unwrap().for_each(drop);
  177. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  178. client: 0,
  179. target: 0,
  180. item_id: 0xF0000001,
  181. area: 0,
  182. unknown: [0; 3]
  183. })))).await.unwrap().for_each(drop);
  184. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  185. assert!(p1_inventory.count() == 30);
  186. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  187. let c2 = ship.clients.get(&ClientId(2)).unwrap();
  188. assert!(c1.character.meseta == 23);
  189. assert!(c2.character.meseta == 277);
  190. }
  191. #[async_std::test]
  192. async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() {
  193. let mut entity_gateway = InMemoryGateway::new();
  194. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  195. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  196. for slot in 0..29 {
  197. entity_gateway.create_item(
  198. item::NewItemEntity {
  199. item: item::ItemDetail::Weapon(
  200. item::weapon::Weapon {
  201. weapon: item::weapon::WeaponType::Saber,
  202. grind: 0,
  203. special: None,
  204. attrs: [None, None, None],
  205. tekked: true,
  206. }
  207. ),
  208. location: item::ItemLocation::Inventory {
  209. character_id: char1.id,
  210. slot: slot,
  211. equipped: false,
  212. }
  213. }).await;
  214. }
  215. entity_gateway.create_item(
  216. item::NewItemEntity {
  217. item: item::ItemDetail::Tool(
  218. item::tool::Tool {
  219. tool: item::tool::ToolType::Monomate,
  220. }
  221. ),
  222. location: item::ItemLocation::Inventory {
  223. character_id: char1.id,
  224. slot: 29,
  225. equipped: false,
  226. }
  227. }).await;
  228. entity_gateway.create_item(
  229. item::NewItemEntity {
  230. item: item::ItemDetail::Tool(
  231. item::tool::Tool {
  232. tool: item::tool::ToolType::Monomate,
  233. }
  234. ),
  235. location: item::ItemLocation::Inventory {
  236. character_id: char2.id,
  237. slot: 0,
  238. equipped: false,
  239. }
  240. }).await;
  241. let mut ship = ShipServerState::new(entity_gateway.clone());
  242. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  243. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  244. join_lobby(&mut ship, ClientId(1)).await;
  245. join_lobby(&mut ship, ClientId(2)).await;
  246. create_room(&mut ship, ClientId(1), "room", "").await;
  247. join_room(&mut ship, ClientId(2), 0).await;
  248. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  249. client: 0,
  250. target: 0,
  251. unknown1: 0,
  252. area: 0,
  253. item_id: 0x210000,
  254. x: 0.0,
  255. y: 0.0,
  256. z: 0.0,
  257. })))).await.unwrap().for_each(drop);
  258. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  259. client: 0,
  260. target: 0,
  261. item_id: 0x210000,
  262. area: 0,
  263. unknown: [0; 3]
  264. })))).await.unwrap().for_each(drop);
  265. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  266. assert!(p1_inventory.count() == 30);
  267. let monomates = p1_inventory.slot(29).unwrap();
  268. assert!(monomates.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 2));
  269. }
  270. #[async_std::test]
  271. async fn test_can_not_pick_up_item_when_inventory_full() {
  272. let mut entity_gateway = InMemoryGateway::new();
  273. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  274. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  275. for slot in 0..30 {
  276. entity_gateway.create_item(
  277. item::NewItemEntity {
  278. item: item::ItemDetail::Weapon(
  279. item::weapon::Weapon {
  280. weapon: item::weapon::WeaponType::Saber,
  281. grind: 0,
  282. special: None,
  283. attrs: [None, None, None],
  284. tekked: true,
  285. }
  286. ),
  287. location: item::ItemLocation::Inventory {
  288. character_id: char1.id,
  289. slot: slot,
  290. equipped: false,
  291. }
  292. }).await;
  293. }
  294. entity_gateway.create_item(
  295. item::NewItemEntity {
  296. item: item::ItemDetail::Weapon(
  297. item::weapon::Weapon {
  298. weapon: item::weapon::WeaponType::Handgun,
  299. grind: 0,
  300. special: None,
  301. attrs: [None, None, None],
  302. tekked: true,
  303. }
  304. ),
  305. location: item::ItemLocation::Inventory {
  306. character_id: char2.id,
  307. slot: 0,
  308. equipped: false,
  309. }
  310. }).await;
  311. let mut ship = ShipServerState::new(entity_gateway.clone());
  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. 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. area: 0,
  333. unknown: [0; 3]
  334. })))).await.unwrap().for_each(drop);
  335. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  336. assert!(p1_inventory.count() == 30);
  337. let floor_item = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0x210000)).unwrap();
  338. assert!(floor_item.item_id == ClientItemId(0x210000));
  339. }
  340. #[async_std::test]
  341. async fn test_can_not_drop_more_meseta_than_is_held() {
  342. let mut entity_gateway = InMemoryGateway::new();
  343. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  344. char1.meseta = 300;
  345. entity_gateway.save_character(&char1).await;
  346. let mut ship = ShipServerState::new(entity_gateway.clone());
  347. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  348. join_lobby(&mut ship, ClientId(1)).await;
  349. create_room(&mut ship, ClientId(1), "room", "").await;
  350. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  351. client: 0,
  352. target: 0,
  353. item_id: 0xFFFFFFFF,
  354. map_area: 0,
  355. x: 0.0,
  356. z: 0.0,
  357. })))).await.unwrap().for_each(drop);
  358. let split_attempt = ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  359. client: 0,
  360. target: 0,
  361. item_id: 0xFFFFFFFF,
  362. amount: 301,
  363. })))).await;
  364. assert!(split_attempt.is_err());
  365. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  366. assert!(c1.character.meseta == 300);
  367. assert!(ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0xF0000001)).is_err())
  368. }
  369. #[async_std::test]
  370. async fn test_pick_up_stack_that_would_exceed_stack_limit() {
  371. let mut entity_gateway = InMemoryGateway::new();
  372. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  373. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  374. for _ in 0..6 {
  375. entity_gateway.create_item(
  376. item::NewItemEntity {
  377. item: item::ItemDetail::Tool(
  378. item::tool::Tool {
  379. tool: item::tool::ToolType::Monomate,
  380. }
  381. ),
  382. location: item::ItemLocation::Inventory {
  383. character_id: char1.id,
  384. slot: 0,
  385. equipped: false,
  386. }
  387. }).await;
  388. }
  389. for _ in 0..6 {
  390. entity_gateway.create_item(
  391. item::NewItemEntity {
  392. item: item::ItemDetail::Tool(
  393. item::tool::Tool {
  394. tool: item::tool::ToolType::Monomate,
  395. }
  396. ),
  397. location: item::ItemLocation::Inventory {
  398. character_id: char2.id,
  399. slot: 0,
  400. equipped: false,
  401. }
  402. }).await;
  403. }
  404. let mut ship = ShipServerState::new(entity_gateway.clone());
  405. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  406. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  407. join_lobby(&mut ship, ClientId(1)).await;
  408. join_lobby(&mut ship, ClientId(2)).await;
  409. create_room(&mut ship, ClientId(1), "room", "").await;
  410. join_room(&mut ship, ClientId(2), 0).await;
  411. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  412. client: 0,
  413. target: 0,
  414. unknown1: 0,
  415. area: 0,
  416. item_id: 0x210000,
  417. x: 0.0,
  418. y: 0.0,
  419. z: 0.0,
  420. })))).await.unwrap().for_each(drop);
  421. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  422. client: 0,
  423. target: 0,
  424. item_id: 0x210000,
  425. area: 0,
  426. unknown: [0; 3]
  427. })))).await.unwrap().for_each(drop);
  428. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  429. let monomates = p1_inventory.slot(0).unwrap();
  430. assert!(monomates.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 6));
  431. let floor_monomates = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0x210000)).unwrap();
  432. assert!(floor_monomates.item == FloorItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 6));
  433. }
  434. #[async_std::test]
  435. async fn test_can_not_pick_up_meseta_when_full() {
  436. let mut entity_gateway = InMemoryGateway::new();
  437. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  438. let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  439. char1.meseta = 999999;
  440. entity_gateway.save_character(&char1).await;
  441. char2.meseta = 300;
  442. entity_gateway.save_character(&char2).await;
  443. let mut ship = ShipServerState::new(entity_gateway.clone());
  444. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  445. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  446. join_lobby(&mut ship, ClientId(1)).await;
  447. join_lobby(&mut ship, ClientId(2)).await;
  448. create_room(&mut ship, ClientId(1), "room", "").await;
  449. join_room(&mut ship, ClientId(2), 0).await;
  450. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  451. client: 0,
  452. target: 0,
  453. item_id: 0xFFFFFFFF,
  454. map_area: 0,
  455. x: 0.0,
  456. z: 0.0,
  457. })))).await.unwrap().for_each(drop);
  458. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  459. client: 0,
  460. target: 0,
  461. item_id: 0xFFFFFFFF,
  462. amount: 23,
  463. })))).await.unwrap().for_each(drop);
  464. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  465. client: 0,
  466. target: 0,
  467. item_id: 0xF0000001,
  468. area: 0,
  469. unknown: [0; 3]
  470. })))).await.unwrap().for_each(drop);
  471. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  472. let c2 = ship.clients.get(&ClientId(2)).unwrap();
  473. assert!(c1.character.meseta == 999999);
  474. assert!(c2.character.meseta == 277);
  475. let floor_meseta = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0xF0000001)).unwrap();
  476. assert!(floor_meseta.item == FloorItemType::Meseta(item::Meseta(23)));
  477. }
  478. #[async_std::test]
  479. async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() {
  480. let mut entity_gateway = InMemoryGateway::new();
  481. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  482. let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  483. char1.meseta = 999998;
  484. entity_gateway.save_character(&char1).await;
  485. char2.meseta = 300;
  486. entity_gateway.save_character(&char2).await;
  487. let mut ship = ShipServerState::new(entity_gateway.clone());
  488. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  489. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  490. join_lobby(&mut ship, ClientId(1)).await;
  491. join_lobby(&mut ship, ClientId(2)).await;
  492. create_room(&mut ship, ClientId(1), "room", "").await;
  493. join_room(&mut ship, ClientId(2), 0).await;
  494. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  495. client: 0,
  496. target: 0,
  497. item_id: 0xFFFFFFFF,
  498. map_area: 0,
  499. x: 0.0,
  500. z: 0.0,
  501. })))).await.unwrap().for_each(drop);
  502. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  503. client: 0,
  504. target: 0,
  505. item_id: 0xFFFFFFFF,
  506. amount: 23,
  507. })))).await.unwrap().for_each(drop);
  508. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  509. client: 0,
  510. target: 0,
  511. item_id: 0xF0000001,
  512. area: 0,
  513. unknown: [0; 3]
  514. })))).await.unwrap().for_each(drop);
  515. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  516. let c2 = ship.clients.get(&ClientId(2)).unwrap();
  517. assert!(c1.character.meseta == 999999);
  518. assert!(c2.character.meseta == 277);
  519. let floor_meseta = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0xF0000001));
  520. assert!(floor_meseta.is_err());
  521. }
  522. #[async_std::test]
  523. async fn test_player_drops_partial_stack_and_other_player_picks_it_up() {
  524. let mut entity_gateway = InMemoryGateway::new();
  525. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  526. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  527. for _ in 0..5 {
  528. entity_gateway.create_item(
  529. item::NewItemEntity {
  530. item: item::ItemDetail::Tool(
  531. item::tool::Tool {
  532. tool: item::tool::ToolType::Monomate,
  533. }
  534. ),
  535. location: item::ItemLocation::Inventory {
  536. character_id: char1.id,
  537. slot: 0,
  538. equipped: false,
  539. }
  540. }).await;
  541. }
  542. let mut ship = ShipServerState::new(entity_gateway.clone());
  543. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  544. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  545. join_lobby(&mut ship, ClientId(1)).await;
  546. join_lobby(&mut ship, ClientId(2)).await;
  547. create_room(&mut ship, ClientId(1), "room", "").await;
  548. join_room(&mut ship, ClientId(2), 0).await;
  549. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  550. client: 0,
  551. target: 0,
  552. item_id: 0x10000,
  553. map_area: 0,
  554. x: 0.0,
  555. z: 0.0,
  556. })))).await.unwrap().for_each(drop);
  557. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  558. client: 0,
  559. target: 0,
  560. item_id: 0x10000,
  561. amount: 2,
  562. })))).await.unwrap().for_each(drop);
  563. ship.handle(ClientId(2), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  564. client: 0,
  565. target: 0,
  566. item_id: 0xF0000001,
  567. area: 0,
  568. unknown: [0; 3]
  569. })))).await.unwrap().for_each(drop);
  570. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  571. assert!(p1_inventory.count() == 1);
  572. let inventory_item = p1_inventory.slot(0).unwrap();
  573. assert!(inventory_item.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 3));
  574. let p2_inventory = ship.item_manager.get_character_inventory(&char2).unwrap();
  575. assert!(p2_inventory.count() == 1);
  576. let inventory_item = p2_inventory.slot(0).unwrap();
  577. assert!(inventory_item.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 2));
  578. }