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.

732 lines
25 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
  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_item_stack_of_items_already_in_inventory() {
  12. let mut entity_gateway = InMemoryGateway::new();
  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. entity_gateway.create_item(
  16. item::NewItemEntity {
  17. item: item::ItemDetail::Tool(
  18. item::tool::Tool {
  19. tool: item::tool::ToolType::Monomate
  20. }
  21. ),
  22. location: item::ItemLocation::Inventory {
  23. character_id: char1.id,
  24. slot: 0,
  25. equipped: false,
  26. }
  27. }).await;
  28. for (slot, tool) in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter().enumerate() {
  29. for _ in 0..5 {
  30. entity_gateway.create_item(
  31. item::NewItemEntity {
  32. item: item::ItemDetail::Tool(
  33. item::tool::Tool {
  34. tool: tool
  35. }
  36. ),
  37. location: item::ItemLocation::Inventory {
  38. character_id: char2.id,
  39. slot: slot,
  40. equipped: false,
  41. }
  42. }).await;
  43. }
  44. }
  45. let mut ship = ShipServerState::new(entity_gateway.clone());
  46. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  47. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  48. join_lobby(&mut ship, ClientId(1)).await;
  49. join_lobby(&mut ship, ClientId(2)).await;
  50. create_room(&mut ship, ClientId(1), "room", "").await;
  51. join_room(&mut ship, ClientId(2), 0).await;
  52. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  53. client: 0,
  54. target: 0,
  55. unknown1: 0,
  56. area: 0,
  57. item_id: 0x210000,
  58. x: 0.0,
  59. y: 0.0,
  60. z: 0.0,
  61. })))).await.unwrap().for_each(drop);
  62. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  63. client: 0,
  64. target: 0,
  65. item_id: 0x210000,
  66. area: 0,
  67. unknown: [0; 3]
  68. })))).await.unwrap().for_each(drop);
  69. let p1_items = entity_gateway.get_items_by_character(&char1).await;
  70. assert!(p1_items.len() == 6);
  71. let p1_item_ids = p1_items.iter().map(|item| {
  72. item.id
  73. }).collect::<Vec<_>>();
  74. assert!(p1_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5), item::ItemEntityId(6)]);
  75. let all_items_are_monomates = p1_items.iter().all(|item| {
  76. match item.item {
  77. item::ItemDetail::Tool(tool) => tool.tool == item::tool::ToolType::Monomate,
  78. _ => false
  79. }
  80. });
  81. assert!(all_items_are_monomates);
  82. }
  83. #[async_std::test]
  84. async fn test_pick_up_item_stack_of_items_not_already_held() {
  85. let mut entity_gateway = InMemoryGateway::new();
  86. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  87. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  88. entity_gateway.create_item(
  89. item::NewItemEntity {
  90. item: item::ItemDetail::Tool(
  91. item::tool::Tool {
  92. tool: item::tool::ToolType::Monomate
  93. }
  94. ),
  95. location: item::ItemLocation::Inventory {
  96. character_id: char2.id,
  97. slot: 0,
  98. equipped: false,
  99. }
  100. }).await;
  101. let mut ship = ShipServerState::new(entity_gateway.clone());
  102. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  103. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  104. join_lobby(&mut ship, ClientId(1)).await;
  105. join_lobby(&mut ship, ClientId(2)).await;
  106. create_room(&mut ship, ClientId(1), "room", "").await;
  107. join_room(&mut ship, ClientId(2), 0).await;
  108. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  109. client: 0,
  110. target: 0,
  111. unknown1: 0,
  112. area: 0,
  113. item_id: 0x210000,
  114. x: 0.0,
  115. y: 0.0,
  116. z: 0.0,
  117. })))).await.unwrap().for_each(drop);
  118. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  119. client: 0,
  120. target: 0,
  121. item_id: 0x210000,
  122. area: 0,
  123. unknown: [0; 3]
  124. })))).await.unwrap().for_each(drop);
  125. let p1_items = entity_gateway.get_items_by_character(&char1).await;
  126. assert!(p1_items.len() == 1);
  127. let first_item = p1_items.get(0).unwrap();
  128. assert!(first_item.id == item::ItemEntityId(1));
  129. assert!(first_item.item == item::ItemDetail::Tool(item::tool::Tool {
  130. tool: item::tool::ToolType::Monomate,
  131. }));
  132. }
  133. #[async_std::test]
  134. async fn test_pick_up_meseta_when_inventory_full() {
  135. let mut entity_gateway = InMemoryGateway::new();
  136. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  137. let (user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  138. for slot in 0..30 {
  139. entity_gateway.create_item(
  140. item::NewItemEntity {
  141. item: item::ItemDetail::Weapon(
  142. item::weapon::Weapon {
  143. weapon: item::weapon::WeaponType::Saber,
  144. grind: 0,
  145. special: None,
  146. attrs: [None, None, None],
  147. tekked: true,
  148. }
  149. ),
  150. location: item::ItemLocation::Inventory {
  151. character_id: char1.id,
  152. slot: slot,
  153. equipped: false,
  154. }
  155. }).await;
  156. }
  157. char2.meseta = 300;
  158. entity_gateway.save_character(&char2).await;
  159. let mut ship = ShipServerState::new(entity_gateway.clone());
  160. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  161. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  162. join_lobby(&mut ship, ClientId(1)).await;
  163. join_lobby(&mut ship, ClientId(2)).await;
  164. create_room(&mut ship, ClientId(1), "room", "").await;
  165. join_room(&mut ship, ClientId(2), 0).await;
  166. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  167. client: 0,
  168. target: 0,
  169. item_id: 0xFFFFFFFF,
  170. map_area: 0,
  171. x: 0.0,
  172. z: 0.0,
  173. })))).await.unwrap().for_each(drop);
  174. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  175. client: 0,
  176. target: 0,
  177. item_id: 0xFFFFFFFF,
  178. amount: 23,
  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: 0xF0000001,
  184. area: 0,
  185. unknown: [0; 3]
  186. })))).await.unwrap().for_each(drop);
  187. let p1_items = entity_gateway.get_items_by_character(&char1).await;
  188. assert!(p1_items.len() == 30);
  189. let characters1 = entity_gateway.get_characters_by_user(&user1).await;
  190. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  191. let characters2 = entity_gateway.get_characters_by_user(&user2).await;
  192. let c2 = characters2.get(0).as_ref().unwrap().as_ref().unwrap();
  193. assert!(c1.meseta == 23);
  194. assert!(c2.meseta == 277);
  195. }
  196. #[async_std::test]
  197. async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() {
  198. let mut entity_gateway = InMemoryGateway::new();
  199. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  200. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  201. for slot in 0..29 {
  202. 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. slot: slot,
  216. equipped: false,
  217. }
  218. }).await;
  219. }
  220. entity_gateway.create_item(
  221. item::NewItemEntity {
  222. item: item::ItemDetail::Tool(
  223. item::tool::Tool {
  224. tool: item::tool::ToolType::Monomate,
  225. }
  226. ),
  227. location: item::ItemLocation::Inventory {
  228. character_id: char1.id,
  229. slot: 29,
  230. equipped: false,
  231. }
  232. }).await;
  233. entity_gateway.create_item(
  234. item::NewItemEntity {
  235. item: item::ItemDetail::Tool(
  236. item::tool::Tool {
  237. tool: item::tool::ToolType::Monomate,
  238. }
  239. ),
  240. location: item::ItemLocation::Inventory {
  241. character_id: char2.id,
  242. slot: 0,
  243. equipped: false,
  244. }
  245. }).await;
  246. let mut ship = ShipServerState::new(entity_gateway.clone());
  247. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  248. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  249. join_lobby(&mut ship, ClientId(1)).await;
  250. join_lobby(&mut ship, ClientId(2)).await;
  251. create_room(&mut ship, ClientId(1), "room", "").await;
  252. join_room(&mut ship, ClientId(2), 0).await;
  253. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  254. client: 0,
  255. target: 0,
  256. unknown1: 0,
  257. area: 0,
  258. item_id: 0x210000,
  259. x: 0.0,
  260. y: 0.0,
  261. z: 0.0,
  262. })))).await.unwrap().for_each(drop);
  263. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  264. client: 0,
  265. target: 0,
  266. item_id: 0x210000,
  267. area: 0,
  268. unknown: [0; 3]
  269. })))).await.unwrap().for_each(drop);
  270. let p1_items = entity_gateway.get_items_by_character(&char1).await;
  271. assert!(p1_items.len() == 31);
  272. let monomate1 = p1_items.get(29).unwrap();
  273. assert!(monomate1.item == item::ItemDetail::Tool(item::tool::Tool {
  274. tool: item::tool::ToolType::Monomate,
  275. }));
  276. let monomate2 = p1_items.get(30).unwrap();
  277. assert!(monomate2.item == item::ItemDetail::Tool(item::tool::Tool {
  278. tool: item::tool::ToolType::Monomate,
  279. }));
  280. }
  281. #[async_std::test]
  282. async fn test_can_not_pick_up_item_when_inventory_full() {
  283. let mut entity_gateway = InMemoryGateway::new();
  284. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  285. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  286. for slot in 0..30 {
  287. entity_gateway.create_item(
  288. item::NewItemEntity {
  289. item: item::ItemDetail::Weapon(
  290. item::weapon::Weapon {
  291. weapon: item::weapon::WeaponType::Saber,
  292. grind: 0,
  293. special: None,
  294. attrs: [None, None, None],
  295. tekked: true,
  296. }
  297. ),
  298. location: item::ItemLocation::Inventory {
  299. character_id: char1.id,
  300. slot: slot,
  301. equipped: false,
  302. }
  303. }).await;
  304. }
  305. entity_gateway.create_item(
  306. item::NewItemEntity {
  307. item: item::ItemDetail::Weapon(
  308. item::weapon::Weapon {
  309. weapon: item::weapon::WeaponType::Handgun,
  310. grind: 0,
  311. special: None,
  312. attrs: [None, None, None],
  313. tekked: true,
  314. }
  315. ),
  316. location: item::ItemLocation::Inventory {
  317. character_id: char2.id,
  318. slot: 0,
  319. equipped: false,
  320. }
  321. }).await;
  322. let mut ship = ShipServerState::new(entity_gateway.clone());
  323. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  324. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  325. join_lobby(&mut ship, ClientId(1)).await;
  326. join_lobby(&mut ship, ClientId(2)).await;
  327. create_room(&mut ship, ClientId(1), "room", "").await;
  328. join_room(&mut ship, ClientId(2), 0).await;
  329. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  330. client: 0,
  331. target: 0,
  332. unknown1: 0,
  333. area: 0,
  334. item_id: 0x210000,
  335. x: 0.0,
  336. y: 0.0,
  337. z: 0.0,
  338. })))).await.unwrap().for_each(drop);
  339. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  340. client: 0,
  341. target: 0,
  342. item_id: 0x210000,
  343. area: 0,
  344. unknown: [0; 3]
  345. })))).await.unwrap().for_each(drop);
  346. let p1_items = entity_gateway.get_items_by_character(&char1).await;
  347. assert!(p1_items.len() == 30);
  348. let p2_items = entity_gateway.get_items_by_character(&char2).await;
  349. assert!(p2_items.len() == 0);
  350. ship.handle(ClientId(2), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  351. client: 0,
  352. target: 0,
  353. item_id: 0x210000,
  354. area: 0,
  355. unknown: [0; 3]
  356. })))).await.unwrap().for_each(drop);
  357. let p2_items = entity_gateway.get_items_by_character(&char2).await;
  358. assert!(p2_items.len() == 1);
  359. }
  360. #[async_std::test]
  361. async fn test_can_not_drop_more_meseta_than_is_held() {
  362. let mut entity_gateway = InMemoryGateway::new();
  363. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  364. char1.meseta = 300;
  365. entity_gateway.save_character(&char1).await;
  366. let mut ship = ShipServerState::new(entity_gateway.clone());
  367. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  368. join_lobby(&mut ship, ClientId(1)).await;
  369. create_room(&mut ship, ClientId(1), "room", "").await;
  370. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  371. client: 0,
  372. target: 0,
  373. item_id: 0xFFFFFFFF,
  374. map_area: 0,
  375. x: 0.0,
  376. z: 0.0,
  377. })))).await.unwrap().for_each(drop);
  378. let split_attempt = ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  379. client: 0,
  380. target: 0,
  381. item_id: 0xFFFFFFFF,
  382. amount: 301,
  383. })))).await;
  384. assert!(split_attempt.is_err());
  385. let characters1 = entity_gateway.get_characters_by_user(&user1).await;
  386. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  387. assert!(c1.meseta == 300);
  388. }
  389. #[async_std::test]
  390. async fn test_pick_up_stack_that_would_exceed_stack_limit() {
  391. let mut entity_gateway = InMemoryGateway::new();
  392. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  393. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  394. for _ in 0..6 {
  395. entity_gateway.create_item(
  396. item::NewItemEntity {
  397. item: item::ItemDetail::Tool(
  398. item::tool::Tool {
  399. tool: item::tool::ToolType::Monomate,
  400. }
  401. ),
  402. location: item::ItemLocation::Inventory {
  403. character_id: char1.id,
  404. slot: 0,
  405. equipped: false,
  406. }
  407. }).await;
  408. }
  409. for _ in 0..6 {
  410. entity_gateway.create_item(
  411. item::NewItemEntity {
  412. item: item::ItemDetail::Tool(
  413. item::tool::Tool {
  414. tool: item::tool::ToolType::Monomate,
  415. }
  416. ),
  417. location: item::ItemLocation::Inventory {
  418. character_id: char2.id,
  419. slot: 0,
  420. equipped: false,
  421. }
  422. }).await;
  423. }
  424. let mut ship = ShipServerState::new(entity_gateway.clone());
  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(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  432. client: 0,
  433. target: 0,
  434. unknown1: 0,
  435. area: 0,
  436. item_id: 0x210000,
  437. x: 0.0,
  438. y: 0.0,
  439. z: 0.0,
  440. })))).await.unwrap().for_each(drop);
  441. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  442. client: 0,
  443. target: 0,
  444. item_id: 0x210000,
  445. area: 0,
  446. unknown: [0; 3]
  447. })))).await.unwrap().collect::<Vec<_>>();
  448. assert!(packets.len() == 0);
  449. let p1_items = entity_gateway.get_items_by_character(&char1).await;
  450. assert!(p1_items.len() == 6);
  451. let p2_items = entity_gateway.get_items_by_character(&char2).await;
  452. assert!(p2_items.len() == 0);
  453. }
  454. #[async_std::test]
  455. async fn test_can_not_pick_up_meseta_when_full() {
  456. let mut entity_gateway = InMemoryGateway::new();
  457. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  458. let (user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  459. char1.meseta = 999999;
  460. entity_gateway.save_character(&char1).await;
  461. char2.meseta = 300;
  462. entity_gateway.save_character(&char2).await;
  463. let mut ship = ShipServerState::new(entity_gateway.clone());
  464. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  465. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  466. join_lobby(&mut ship, ClientId(1)).await;
  467. join_lobby(&mut ship, ClientId(2)).await;
  468. create_room(&mut ship, ClientId(1), "room", "").await;
  469. join_room(&mut ship, ClientId(2), 0).await;
  470. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  471. client: 0,
  472. target: 0,
  473. item_id: 0xFFFFFFFF,
  474. map_area: 0,
  475. x: 0.0,
  476. z: 0.0,
  477. })))).await.unwrap().for_each(drop);
  478. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  479. client: 0,
  480. target: 0,
  481. item_id: 0xFFFFFFFF,
  482. amount: 23,
  483. })))).await.unwrap().for_each(drop);
  484. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  485. client: 0,
  486. target: 0,
  487. item_id: 0xF0000001,
  488. area: 0,
  489. unknown: [0; 3]
  490. })))).await.unwrap().collect::<Vec<_>>();
  491. println!("pkts {:?}", packets);
  492. assert!(packets.len() == 0);
  493. let characters1 = entity_gateway.get_characters_by_user(&user1).await;
  494. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  495. let characters2 = entity_gateway.get_characters_by_user(&user2).await;
  496. let c2 = characters2.get(0).as_ref().unwrap().as_ref().unwrap();
  497. assert!(c1.meseta == 999999);
  498. assert!(c2.meseta == 277);
  499. }
  500. #[async_std::test]
  501. async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() {
  502. let mut entity_gateway = InMemoryGateway::new();
  503. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  504. let (user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  505. char1.meseta = 999998;
  506. entity_gateway.save_character(&char1).await;
  507. char2.meseta = 300;
  508. entity_gateway.save_character(&char2).await;
  509. let mut ship = ShipServerState::new(entity_gateway.clone());
  510. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  511. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  512. join_lobby(&mut ship, ClientId(1)).await;
  513. join_lobby(&mut ship, ClientId(2)).await;
  514. create_room(&mut ship, ClientId(1), "room", "").await;
  515. join_room(&mut ship, ClientId(2), 0).await;
  516. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  517. client: 0,
  518. target: 0,
  519. item_id: 0xFFFFFFFF,
  520. map_area: 0,
  521. x: 0.0,
  522. z: 0.0,
  523. })))).await.unwrap().for_each(drop);
  524. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  525. client: 0,
  526. target: 0,
  527. item_id: 0xFFFFFFFF,
  528. amount: 23,
  529. })))).await.unwrap().for_each(drop);
  530. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  531. client: 0,
  532. target: 0,
  533. item_id: 0xF0000001,
  534. area: 0,
  535. unknown: [0; 3]
  536. })))).await.unwrap().for_each(drop);
  537. let characters1 = entity_gateway.get_characters_by_user(&user1).await;
  538. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  539. let characters2 = entity_gateway.get_characters_by_user(&user2).await;
  540. let c2 = characters2.get(0).as_ref().unwrap().as_ref().unwrap();
  541. assert!(c1.meseta == 999999);
  542. assert!(c2.meseta == 277);
  543. }
  544. #[async_std::test]
  545. async fn test_player_drops_partial_stack_and_other_player_picks_it_up() {
  546. let mut entity_gateway = InMemoryGateway::new();
  547. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  548. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  549. for _ in 0..5 {
  550. entity_gateway.create_item(
  551. item::NewItemEntity {
  552. item: item::ItemDetail::Tool(
  553. item::tool::Tool {
  554. tool: item::tool::ToolType::Monomate,
  555. }
  556. ),
  557. location: item::ItemLocation::Inventory {
  558. character_id: char1.id,
  559. slot: 0,
  560. equipped: false,
  561. }
  562. }).await;
  563. }
  564. let mut ship = ShipServerState::new(entity_gateway.clone());
  565. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  566. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  567. join_lobby(&mut ship, ClientId(1)).await;
  568. join_lobby(&mut ship, ClientId(2)).await;
  569. create_room(&mut ship, ClientId(1), "room", "").await;
  570. join_room(&mut ship, ClientId(2), 0).await;
  571. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  572. client: 0,
  573. target: 0,
  574. item_id: 0x10000,
  575. map_area: 0,
  576. x: 0.0,
  577. z: 0.0,
  578. })))).await.unwrap().for_each(drop);
  579. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  580. client: 0,
  581. target: 0,
  582. item_id: 0x10000,
  583. amount: 2,
  584. })))).await.unwrap().for_each(drop);
  585. ship.handle(ClientId(2), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  586. client: 0,
  587. target: 0,
  588. item_id: 0xF0000001,
  589. area: 0,
  590. unknown: [0; 3]
  591. })))).await.unwrap().for_each(drop);
  592. let p1_items = entity_gateway.get_items_by_character(&char1).await;
  593. assert!(p1_items.len() == 3);
  594. let p1_item_ids = p1_items.iter().map(|item| {
  595. item.id
  596. }).collect::<Vec<_>>();
  597. assert!(p1_item_ids == vec![item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5)]);
  598. let all_items_are_monomates = p1_items.iter().all(|item| {
  599. match item.item {
  600. item::ItemDetail::Tool(tool) => tool.tool == item::tool::ToolType::Monomate,
  601. _ => false
  602. }
  603. });
  604. assert!(all_items_are_monomates);
  605. let p2_items = entity_gateway.get_items_by_character(&char2).await;
  606. assert!(p2_items.len() == 2);
  607. let p2_item_ids = p2_items.iter().map(|item| {
  608. item.id
  609. }).collect::<Vec<_>>();
  610. assert!(p2_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  611. let all_items_are_monomates = p1_items.iter().all(|item| {
  612. match item.item {
  613. item::ItemDetail::Tool(tool) => tool.tool == item::tool::ToolType::Monomate,
  614. _ => false
  615. }
  616. });
  617. assert!(all_items_are_monomates);
  618. }