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.

565 lines
20 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
  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, SendShipPacket};
  5. use elseware::ship::room::Difficulty;
  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_player_opens_weapon_shop() {
  13. let mut entity_gateway = InMemoryGateway::new();
  14. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  15. char1.exp = 80000000;
  16. entity_gateway.save_character(&char1).await.unwrap();
  17. let mut ship = ShipServerState::builder()
  18. .gateway(entity_gateway.clone())
  19. .build();
  20. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  21. join_lobby(&mut ship, ClientId(1)).await;
  22. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  23. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  24. client: 255,
  25. target: 255,
  26. shop_type: 1
  27. })))).await.unwrap().collect::<Vec<_>>();
  28. assert_eq!(packets.len(), 1);
  29. match &packets[0].1 {
  30. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  31. assert_eq!(shop_list.items.len(), 16)
  32. }
  33. _ => panic!("")
  34. }
  35. }
  36. #[async_std::test]
  37. async fn test_player_opens_tool_shop() {
  38. let mut entity_gateway = InMemoryGateway::new();
  39. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  40. char1.exp = 80000000;
  41. entity_gateway.save_character(&char1).await.unwrap();
  42. let mut ship = ShipServerState::builder()
  43. .gateway(entity_gateway.clone())
  44. .build();
  45. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  46. join_lobby(&mut ship, ClientId(1)).await;
  47. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  48. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  49. client: 255,
  50. target: 255,
  51. shop_type: 0
  52. })))).await.unwrap().collect::<Vec<_>>();
  53. assert_eq!(packets.len(), 1);
  54. match &packets[0].1 {
  55. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  56. assert_eq!(shop_list.items.len(), 18)
  57. }
  58. _ => panic!("")
  59. }
  60. }
  61. #[async_std::test]
  62. async fn test_player_opens_armor_shop() {
  63. let mut entity_gateway = InMemoryGateway::new();
  64. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  65. char1.exp = 80000000;
  66. entity_gateway.save_character(&char1).await.unwrap();
  67. let mut ship = ShipServerState::builder()
  68. .gateway(entity_gateway.clone())
  69. .build();
  70. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  71. join_lobby(&mut ship, ClientId(1)).await;
  72. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  73. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  74. client: 255,
  75. target: 255,
  76. shop_type: 2
  77. })))).await.unwrap().collect::<Vec<_>>();
  78. assert_eq!(packets.len(), 1);
  79. match &packets[0].1 {
  80. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  81. assert_eq!(shop_list.items.len(), 21)
  82. }
  83. _ => panic!("")
  84. }
  85. }
  86. #[async_std::test]
  87. async fn test_player_buys_from_weapon_shop() {
  88. let mut entity_gateway = InMemoryGateway::new();
  89. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  90. char1.exp = 80000000;
  91. char1.meseta = 999999;
  92. entity_gateway.save_character(&char1).await.unwrap();
  93. let mut ship = ShipServerState::builder()
  94. .gateway(entity_gateway.clone())
  95. .build();
  96. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  97. join_lobby(&mut ship, ClientId(1)).await;
  98. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  99. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  100. client: 255,
  101. target: 255,
  102. shop_type: 1
  103. })))).await.unwrap().for_each(drop);
  104. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  105. client: 255,
  106. target: 255,
  107. item_id: 0x10000,
  108. shop_type: 1,
  109. shop_index: 0,
  110. amount: 1,
  111. unknown1: 0,
  112. })))).await.unwrap().for_each(drop);
  113. let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  114. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  115. assert!(c1.meseta < 999999);
  116. let p1_items = entity_gateway.get_items_by_character(&char1).await.unwrap();
  117. assert_eq!(p1_items.len(), 1);
  118. }
  119. #[async_std::test]
  120. async fn test_player_buys_from_tool_shop() {
  121. let mut entity_gateway = InMemoryGateway::new();
  122. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  123. char1.exp = 80000000;
  124. char1.meseta = 999999;
  125. entity_gateway.save_character(&char1).await.unwrap();
  126. let mut ship = ShipServerState::builder()
  127. .gateway(entity_gateway.clone())
  128. .build();
  129. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  130. join_lobby(&mut ship, ClientId(1)).await;
  131. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  132. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  133. client: 255,
  134. target: 255,
  135. shop_type: 0,
  136. })))).await.unwrap().for_each(drop);
  137. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  138. client: 255,
  139. target: 255,
  140. item_id: 0x10000,
  141. shop_type: 0,
  142. shop_index: 0,
  143. amount: 1,
  144. unknown1: 0,
  145. })))).await.unwrap().for_each(drop);
  146. let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  147. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  148. assert!(c1.meseta < 999999);
  149. let p1_items = entity_gateway.get_items_by_character(&char1).await.unwrap();
  150. assert_eq!(p1_items.len(), 1);
  151. }
  152. #[async_std::test]
  153. async fn test_player_buys_multiple_from_tool_shop() {
  154. let mut entity_gateway = InMemoryGateway::new();
  155. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  156. char1.exp = 80000000;
  157. char1.meseta = 999999;
  158. entity_gateway.save_character(&char1).await.unwrap();
  159. let mut ship = ShipServerState::builder()
  160. .gateway(entity_gateway.clone())
  161. .build();
  162. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  163. join_lobby(&mut ship, ClientId(1)).await;
  164. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  165. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  166. client: 255,
  167. target: 255,
  168. shop_type: 0,
  169. })))).await.unwrap().for_each(drop);
  170. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  171. client: 255,
  172. target: 255,
  173. item_id: 0x10000,
  174. shop_type: 0,
  175. shop_index: 0,
  176. amount: 5,
  177. unknown1: 0,
  178. })))).await.unwrap().for_each(drop);
  179. let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  180. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  181. assert!(c1.meseta < 999999);
  182. let p1_items = entity_gateway.get_items_by_character(&char1).await.unwrap();
  183. assert_eq!(p1_items.len(), 5);
  184. }
  185. #[async_std::test]
  186. async fn test_player_buys_from_armor_shop() {
  187. let mut entity_gateway = InMemoryGateway::new();
  188. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  189. char1.exp = 80000000;
  190. char1.meseta = 999999;
  191. entity_gateway.save_character(&char1).await.unwrap();
  192. let mut ship = ShipServerState::builder()
  193. .gateway(entity_gateway.clone())
  194. .build();
  195. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  196. join_lobby(&mut ship, ClientId(1)).await;
  197. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  198. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  199. client: 255,
  200. target: 255,
  201. shop_type: 2
  202. })))).await.unwrap().for_each(drop);
  203. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  204. client: 255,
  205. target: 255,
  206. item_id: 0x10000,
  207. shop_type: 2,
  208. shop_index: 0,
  209. amount: 1,
  210. unknown1: 0,
  211. })))).await.unwrap().for_each(drop);
  212. let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  213. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  214. assert!(c1.meseta < 999999);
  215. let p1_items = entity_gateway.get_items_by_character(&char1).await.unwrap();
  216. assert_eq!(p1_items.len(), 1);
  217. }
  218. #[async_std::test]
  219. async fn test_player_sells_to_shop() {
  220. }
  221. #[async_std::test]
  222. async fn test_other_clients_see_purchase() {
  223. let mut entity_gateway = InMemoryGateway::new();
  224. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  225. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  226. char1.exp = 80000000;
  227. char1.meseta = 999999;
  228. entity_gateway.save_character(&char1).await.unwrap();
  229. let mut ship = ShipServerState::builder()
  230. .gateway(entity_gateway.clone())
  231. .build();
  232. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  233. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  234. join_lobby(&mut ship, ClientId(1)).await;
  235. join_lobby(&mut ship, ClientId(2)).await;
  236. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  237. join_room(&mut ship, ClientId(2), 0).await;
  238. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  239. client: 255,
  240. target: 255,
  241. shop_type: 1
  242. })))).await.unwrap().for_each(drop);
  243. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  244. client: 255,
  245. target: 255,
  246. item_id: 0x10000,
  247. shop_type: 1,
  248. shop_index: 0,
  249. amount: 1,
  250. unknown1: 0,
  251. })))).await.unwrap().collect::<Vec<_>>();
  252. assert_eq!(packets.len(), 1);
  253. assert_eq!(packets[0].0, ClientId(2));
  254. match &packets[0].1 {
  255. SendShipPacket::Message(Message{msg: GameMessage::CreateItem(_)}) => {},
  256. _ => panic!(""),
  257. }
  258. }
  259. #[async_std::test]
  260. async fn test_other_clients_see_stacked_purchase() {
  261. let mut entity_gateway = InMemoryGateway::new();
  262. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  263. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  264. char1.exp = 80000000;
  265. char1.meseta = 999999;
  266. entity_gateway.save_character(&char1).await.unwrap();
  267. entity_gateway.create_item(
  268. item::NewItemEntity {
  269. item: item::ItemDetail::Tool(
  270. item::tool::Tool {
  271. tool: item::tool::ToolType::Monomate
  272. }
  273. ),
  274. location: item::ItemLocation::Inventory {
  275. character_id: char1.id,
  276. slot: 0,
  277. equipped: false,
  278. }
  279. }).await.unwrap();
  280. let mut ship = ShipServerState::builder()
  281. .gateway(entity_gateway.clone())
  282. .build();
  283. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  284. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  285. join_lobby(&mut ship, ClientId(1)).await;
  286. join_lobby(&mut ship, ClientId(2)).await;
  287. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  288. join_room(&mut ship, ClientId(2), 0).await;
  289. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  290. client: 255,
  291. target: 255,
  292. shop_type: 1
  293. })))).await.unwrap().for_each(drop);
  294. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  295. client: 255,
  296. target: 255,
  297. item_id: 0x10000,
  298. shop_type: 1,
  299. shop_index: 0,
  300. amount: 1,
  301. unknown1: 0,
  302. })))).await.unwrap().collect::<Vec<_>>();
  303. assert_eq!(packets.len(), 1);
  304. assert_eq!(packets[0].0, ClientId(2));
  305. match &packets[0].1 {
  306. SendShipPacket::Message(Message{msg: GameMessage::CreateItem(_)}) => {},
  307. _ => panic!(""),
  308. }
  309. }
  310. #[async_std::test]
  311. async fn test_buying_item_without_enough_mseseta() {
  312. let mut entity_gateway = InMemoryGateway::new();
  313. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  314. let mut ship = ShipServerState::builder()
  315. .gateway(entity_gateway.clone())
  316. .build();
  317. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  318. join_lobby(&mut ship, ClientId(1)).await;
  319. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  320. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  321. client: 255,
  322. target: 255,
  323. shop_type: 1
  324. })))).await.unwrap().for_each(drop);
  325. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  326. client: 255,
  327. target: 255,
  328. item_id: 0x10000,
  329. shop_type: 1,
  330. shop_index: 0,
  331. amount: 1,
  332. unknown1: 0,
  333. })))).await;
  334. assert!(packets.is_err());
  335. let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  336. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  337. assert_eq!(c1.meseta, 0);
  338. let p1_items = entity_gateway.get_items_by_character(&char1).await.unwrap();
  339. assert_eq!(p1_items.len(), 0);
  340. }
  341. #[async_std::test]
  342. async fn test_player_double_buys_from_tool_shop() {
  343. let mut entity_gateway = InMemoryGateway::new();
  344. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  345. char1.exp = 80000000;
  346. char1.meseta = 999999;
  347. entity_gateway.save_character(&char1).await.unwrap();
  348. let mut ship = ShipServerState::builder()
  349. .gateway(entity_gateway.clone())
  350. .build();
  351. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  352. join_lobby(&mut ship, ClientId(1)).await;
  353. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  354. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  355. client: 255,
  356. target: 255,
  357. shop_type: 0,
  358. })))).await.unwrap().for_each(drop);
  359. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  360. client: 255,
  361. target: 255,
  362. item_id: 0x10000,
  363. shop_type: 0,
  364. shop_index: 0,
  365. amount: 3,
  366. unknown1: 0,
  367. })))).await.unwrap().for_each(drop);
  368. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  369. client: 255,
  370. target: 255,
  371. item_id: 0x10001,
  372. shop_type: 0,
  373. shop_index: 1,
  374. amount: 2,
  375. unknown1: 0,
  376. })))).await.unwrap().for_each(drop);
  377. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  378. client: 255,
  379. target: 255,
  380. item_id: 0x10002,
  381. shop_type: 0,
  382. shop_index: 0,
  383. amount: 4,
  384. unknown1: 0,
  385. })))).await.unwrap().for_each(drop);
  386. let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap();
  387. let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap();
  388. assert!(c1.meseta < 999999);
  389. let p1_items = entity_gateway.get_items_by_character(&char1).await.unwrap();
  390. assert_eq!(p1_items.len(), 9);
  391. }
  392. #[async_std::test]
  393. async fn test_techs_disappear_from_shop_when_bought() {
  394. let mut entity_gateway = InMemoryGateway::new();
  395. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  396. char1.exp = 80000000;
  397. char1.meseta = 999999;
  398. entity_gateway.save_character(&char1).await.unwrap();
  399. let mut ship = ShipServerState::builder()
  400. .gateway(entity_gateway.clone())
  401. .build();
  402. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  403. join_lobby(&mut ship, ClientId(1)).await;
  404. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  405. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  406. client: 255,
  407. target: 255,
  408. shop_type: 0,
  409. })))).await.unwrap().collect::<Vec<_>>();
  410. let first_tech = match &packets[0].1 {
  411. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  412. shop_list.items.iter()
  413. .enumerate()
  414. .filter(|(_, item)| {
  415. item.item_bytes[0] == 3 && item.item_bytes[1] == 2
  416. })
  417. .nth(0).unwrap().0
  418. },
  419. _ => panic!(""),
  420. };
  421. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  422. client: 255,
  423. target: 255,
  424. item_id: 0x10000,
  425. shop_type: 0,
  426. shop_index: first_tech as u8,
  427. amount: 1,
  428. unknown1: 0,
  429. })))).await.unwrap().for_each(drop);
  430. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  431. client: 255,
  432. target: 255,
  433. item_id: 0x10001,
  434. shop_type: 0,
  435. shop_index: first_tech as u8,
  436. amount: 1,
  437. unknown1: 0,
  438. })))).await.unwrap().for_each(drop);
  439. let p1_items = entity_gateway.get_items_by_character(&char1).await.unwrap();
  440. assert!(p1_items[0].item != p1_items[1].item);
  441. }
  442. // TOOD: this is not deterministic and can randomly fail
  443. #[async_std::test]
  444. async fn test_units_disappear_from_shop_when_bought() {
  445. let mut entity_gateway = InMemoryGateway::new();
  446. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  447. char1.exp = 80000000;
  448. char1.meseta = 999999;
  449. entity_gateway.save_character(&char1).await.unwrap();
  450. let mut ship = ShipServerState::builder()
  451. .gateway(entity_gateway.clone())
  452. .build();
  453. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  454. join_lobby(&mut ship, ClientId(1)).await;
  455. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  456. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  457. client: 255,
  458. target: 255,
  459. shop_type: 2,
  460. })))).await.unwrap().collect::<Vec<_>>();
  461. let first_unit = match &packets[0].1 {
  462. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  463. shop_list.items.iter()
  464. .enumerate()
  465. .filter(|(_, item)| {
  466. item.item_bytes[0] == 1 && item.item_bytes[1] == 3
  467. })
  468. .nth(0).unwrap().0
  469. },
  470. _ => panic!(""),
  471. };
  472. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  473. client: 255,
  474. target: 255,
  475. item_id: 0x10000,
  476. shop_type: 2,
  477. shop_index: first_unit as u8,
  478. amount: 1,
  479. unknown1: 0,
  480. })))).await.unwrap().for_each(drop);
  481. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  482. client: 255,
  483. target: 255,
  484. item_id: 0x10001,
  485. shop_type: 2,
  486. shop_index: first_unit as u8,
  487. amount: 1,
  488. unknown1: 0,
  489. })))).await.unwrap().for_each(drop);
  490. let p1_items = entity_gateway.get_items_by_character(&char1).await.unwrap();
  491. assert!(p1_items[0].item != p1_items[1].item);
  492. }