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.

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