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.

1107 lines
40 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
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 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
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
3 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::default();
  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 = Box::new(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::default();
  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 = Box::new(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::default();
  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 = Box::new(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::default();
  89. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  90. char1.exp = 80000000;
  91. entity_gateway.save_character(&char1).await.unwrap();
  92. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  93. let mut ship = Box::new(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 c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  114. assert!(c1_meseta.0 < 999999);
  115. //let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap();
  116. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  117. assert_eq!(p1_items.items.len(), 1);
  118. }
  119. #[async_std::test]
  120. async fn test_player_buys_from_tool_shop() {
  121. let mut entity_gateway = InMemoryGateway::default();
  122. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  123. char1.exp = 80000000;
  124. entity_gateway.save_character(&char1).await.unwrap();
  125. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  126. let mut ship = Box::new(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 c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  147. assert!(c1_meseta.0 < 999999);
  148. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  149. assert_eq!(p1_items.items.len(), 1);
  150. }
  151. #[async_std::test]
  152. async fn test_player_buys_multiple_from_tool_shop() {
  153. let mut entity_gateway = InMemoryGateway::default();
  154. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  155. char1.exp = 80000000;
  156. entity_gateway.save_character(&char1).await.unwrap();
  157. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  158. let mut ship = Box::new(ShipServerState::builder()
  159. .gateway(entity_gateway.clone())
  160. .build());
  161. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  162. join_lobby(&mut ship, ClientId(1)).await;
  163. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  164. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  165. client: 255,
  166. target: 255,
  167. shop_type: 0,
  168. })))).await.unwrap().for_each(drop);
  169. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  170. client: 255,
  171. target: 255,
  172. item_id: 0x10000,
  173. shop_type: 0,
  174. shop_index: 0,
  175. amount: 5,
  176. unknown1: 0,
  177. })))).await.unwrap().for_each(drop);
  178. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  179. assert_eq!(c1_meseta.0, 999749);
  180. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  181. assert_eq!(p1_items.items.len(), 1);
  182. p1_items.items[0].with_stacked(|item| {
  183. assert_eq!(item.len(), 5);
  184. assert_eq!(item[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Monomate));
  185. }).unwrap();
  186. }
  187. #[async_std::test]
  188. async fn test_player_buys_from_armor_shop() {
  189. let mut entity_gateway = InMemoryGateway::default();
  190. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  191. char1.exp = 80000000;
  192. entity_gateway.save_character(&char1).await.unwrap();
  193. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  194. let mut ship = Box::new(ShipServerState::builder()
  195. .gateway(entity_gateway.clone())
  196. .build());
  197. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  198. join_lobby(&mut ship, ClientId(1)).await;
  199. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  200. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  201. client: 255,
  202. target: 255,
  203. shop_type: 2
  204. })))).await.unwrap().for_each(drop);
  205. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  206. client: 255,
  207. target: 255,
  208. item_id: 0x10000,
  209. shop_type: 2,
  210. shop_index: 0,
  211. amount: 1,
  212. unknown1: 0,
  213. })))).await.unwrap().for_each(drop);
  214. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  215. assert!(c1_meseta.0 < 999999);
  216. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  217. assert_eq!(p1_items.items.len(), 1);
  218. }
  219. #[async_std::test]
  220. async fn test_player_sells_3_attr_weapon_to_shop() {
  221. let mut entity_gateway = InMemoryGateway::default();
  222. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  223. let mut p1_inv = Vec::new();
  224. p1_inv.push(entity_gateway.create_item(
  225. item::NewItemEntity {
  226. item: item::ItemDetail::Weapon(
  227. item::weapon::Weapon {
  228. weapon: item::weapon::WeaponType::Vulcan,
  229. grind: 5,
  230. special: Some(item::weapon::WeaponSpecial::Charge),
  231. attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}),
  232. Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
  233. Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),],
  234. tekked: true,
  235. }
  236. ),
  237. }).await.unwrap());
  238. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  239. let mut ship = Box::new(ShipServerState::builder()
  240. .gateway(entity_gateway.clone())
  241. .build());
  242. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  243. join_lobby(&mut ship, ClientId(1)).await;
  244. create_room(&mut ship, ClientId(1), "room", "").await;
  245. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  246. client: 0,
  247. target: 0,
  248. item_id: 0x10000,
  249. amount: 1,
  250. })))).await.unwrap().for_each(drop);
  251. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  252. assert_eq!(c1_meseta.0, 4406);
  253. }
  254. #[async_std::test]
  255. async fn test_other_clients_see_purchase() {
  256. let mut entity_gateway = InMemoryGateway::default();
  257. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  258. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  259. char1.exp = 80000000;
  260. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  261. entity_gateway.save_character(&char1).await.unwrap();
  262. let mut ship = Box::new(ShipServerState::builder()
  263. .gateway(entity_gateway.clone())
  264. .build());
  265. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  266. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  267. join_lobby(&mut ship, ClientId(1)).await;
  268. join_lobby(&mut ship, ClientId(2)).await;
  269. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Normal).await;
  270. join_room(&mut ship, ClientId(2), 0).await;
  271. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  272. client: 255,
  273. target: 255,
  274. shop_type: 1
  275. })))).await.unwrap().for_each(drop);
  276. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  277. client: 255,
  278. target: 255,
  279. item_id: 0x10000,
  280. shop_type: 1,
  281. shop_index: 0,
  282. amount: 1,
  283. unknown1: 0,
  284. })))).await.unwrap().collect::<Vec<_>>();
  285. assert_eq!(packets.len(), 1);
  286. assert_eq!(packets[0].0, ClientId(2));
  287. match &packets[0].1 {
  288. SendShipPacket::Message(Message{msg: GameMessage::CreateItem(_)}) => {},
  289. _ => panic!(""),
  290. }
  291. }
  292. #[async_std::test]
  293. async fn test_other_clients_see_stacked_purchase() {
  294. let mut entity_gateway = InMemoryGateway::default();
  295. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  296. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  297. char1.exp = 80000000;
  298. entity_gateway.save_character(&char1).await.unwrap();
  299. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  300. entity_gateway.create_item(
  301. item::NewItemEntity {
  302. item: item::ItemDetail::Tool(
  303. item::tool::Tool {
  304. tool: item::tool::ToolType::Monomate
  305. }
  306. ),
  307. }).await.unwrap();
  308. let mut ship = Box::new(ShipServerState::builder()
  309. .gateway(entity_gateway.clone())
  310. .build());
  311. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  312. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  313. join_lobby(&mut ship, ClientId(1)).await;
  314. join_lobby(&mut ship, ClientId(2)).await;
  315. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Normal).await;
  316. join_room(&mut ship, ClientId(2), 0).await;
  317. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  318. client: 255,
  319. target: 255,
  320. shop_type: 1
  321. })))).await.unwrap().for_each(drop);
  322. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  323. client: 255,
  324. target: 255,
  325. item_id: 0x10000,
  326. shop_type: 1,
  327. shop_index: 0,
  328. amount: 1,
  329. unknown1: 0,
  330. })))).await.unwrap().collect::<Vec<_>>();
  331. assert_eq!(packets.len(), 1);
  332. assert_eq!(packets[0].0, ClientId(2));
  333. match &packets[0].1 {
  334. SendShipPacket::Message(Message{msg: GameMessage::CreateItem(_)}) => {},
  335. _ => panic!(""),
  336. }
  337. }
  338. #[async_std::test]
  339. async fn test_buying_item_without_enough_mseseta() {
  340. let mut entity_gateway = InMemoryGateway::default();
  341. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  342. let mut ship = Box::new(ShipServerState::builder()
  343. .gateway(entity_gateway.clone())
  344. .build());
  345. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  346. join_lobby(&mut ship, ClientId(1)).await;
  347. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Normal).await;
  348. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  349. client: 255,
  350. target: 255,
  351. shop_type: 1
  352. })))).await.unwrap().for_each(drop);
  353. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  354. client: 255,
  355. target: 255,
  356. item_id: 0x10000,
  357. shop_type: 1,
  358. shop_index: 0,
  359. amount: 1,
  360. unknown1: 0,
  361. })))).await;
  362. assert!(packets.is_err());
  363. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  364. assert_eq!(c1_meseta.0, 0);
  365. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  366. assert_eq!(p1_items.items.len(), 0);
  367. }
  368. #[async_std::test]
  369. async fn test_player_double_buys_from_tool_shop() {
  370. let mut entity_gateway = InMemoryGateway::default();
  371. let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  372. char1.exp = 80000000;
  373. entity_gateway.save_character(&char1).await.unwrap();
  374. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  375. let mut ship = Box::new(ShipServerState::builder()
  376. .gateway(entity_gateway.clone())
  377. .build());
  378. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  379. join_lobby(&mut ship, ClientId(1)).await;
  380. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  381. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  382. client: 255,
  383. target: 255,
  384. shop_type: 0,
  385. })))).await.unwrap().for_each(drop);
  386. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  387. client: 255,
  388. target: 255,
  389. item_id: 0x10000,
  390. shop_type: 0,
  391. shop_index: 0,
  392. amount: 3,
  393. unknown1: 0,
  394. })))).await.unwrap().for_each(drop);
  395. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  396. client: 255,
  397. target: 255,
  398. item_id: 0x10001,
  399. shop_type: 0,
  400. shop_index: 1,
  401. amount: 2,
  402. unknown1: 0,
  403. })))).await.unwrap().for_each(drop);
  404. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  405. client: 255,
  406. target: 255,
  407. item_id: 0x10002,
  408. shop_type: 0,
  409. shop_index: 0,
  410. amount: 4,
  411. unknown1: 0,
  412. })))).await.unwrap().for_each(drop);
  413. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  414. assert!(c1_meseta.0 < 999999);
  415. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  416. assert_eq!(p1_items.items.len(), 2);
  417. p1_items.items[0].with_stacked(|item| {
  418. assert_eq!(item.len(), 7);
  419. assert_eq!(item[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Monomate));
  420. }).unwrap();
  421. p1_items.items[1].with_stacked(|item| {
  422. assert_eq!(item.len(), 2);
  423. assert_eq!(item[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Dimate));
  424. }).unwrap();
  425. }
  426. #[async_std::test]
  427. async fn test_techs_disappear_from_shop_when_bought() {
  428. let mut entity_gateway = InMemoryGateway::default();
  429. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  430. char1.exp = 80000000;
  431. entity_gateway.save_character(&char1).await.unwrap();
  432. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  433. let mut ship = Box::new(ShipServerState::builder()
  434. .gateway(entity_gateway.clone())
  435. .build());
  436. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  437. join_lobby(&mut ship, ClientId(1)).await;
  438. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  439. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  440. client: 255,
  441. target: 255,
  442. shop_type: 0,
  443. })))).await.unwrap().collect::<Vec<_>>();
  444. let first_tech = match &packets[0].1 {
  445. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  446. shop_list.items.iter()
  447. .enumerate()
  448. .filter(|(_, item)| {
  449. item.item_bytes[0] == 3 && item.item_bytes[1] == 2
  450. })
  451. .nth(0).unwrap().0
  452. },
  453. _ => panic!(""),
  454. };
  455. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  456. client: 255,
  457. target: 255,
  458. item_id: 0x10000,
  459. shop_type: 0,
  460. shop_index: first_tech as u8,
  461. amount: 1,
  462. unknown1: 0,
  463. })))).await.unwrap().for_each(drop);
  464. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  465. client: 255,
  466. target: 255,
  467. item_id: 0x10001,
  468. shop_type: 0,
  469. shop_index: first_tech as u8,
  470. amount: 1,
  471. unknown1: 0,
  472. })))).await.unwrap().for_each(drop);
  473. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  474. p1_items.items[0].with_individual(|item1| {
  475. p1_items.items[1].with_individual(|item2| {
  476. assert_ne!(item1, item2);
  477. }).unwrap();
  478. }).unwrap();
  479. }
  480. // TOOD: this is not deterministic and can randomly fail
  481. #[async_std::test]
  482. async fn test_units_disappear_from_shop_when_bought() {
  483. let mut entity_gateway = InMemoryGateway::default();
  484. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  485. char1.exp = 80000000;
  486. entity_gateway.save_character(&char1).await.unwrap();
  487. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  488. let mut ship = Box::new(ShipServerState::builder()
  489. .gateway(entity_gateway.clone())
  490. .build());
  491. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  492. join_lobby(&mut ship, ClientId(1)).await;
  493. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  494. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  495. client: 255,
  496. target: 255,
  497. shop_type: 2,
  498. })))).await.unwrap().collect::<Vec<_>>();
  499. let first_unit = match &packets[0].1 {
  500. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  501. shop_list.items.iter()
  502. .enumerate()
  503. .filter(|(_, item)| {
  504. item.item_bytes[0] == 1 && item.item_bytes[1] == 3
  505. })
  506. .nth(0).unwrap().0
  507. },
  508. _ => panic!(""),
  509. };
  510. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  511. client: 255,
  512. target: 255,
  513. item_id: 0x10000,
  514. shop_type: 2,
  515. shop_index: first_unit as u8,
  516. amount: 1,
  517. unknown1: 0,
  518. })))).await.unwrap().for_each(drop);
  519. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  520. client: 255,
  521. target: 255,
  522. item_id: 0x10001,
  523. shop_type: 2,
  524. shop_index: first_unit as u8,
  525. amount: 1,
  526. unknown1: 0,
  527. })))).await.unwrap().for_each(drop);
  528. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  529. p1_items.items[0].with_individual(|item1| {
  530. p1_items.items[1].with_individual(|item2| {
  531. assert_ne!(item1, item2);
  532. }).unwrap();
  533. }).unwrap();
  534. }
  535. #[async_std::test]
  536. async fn test_player_sells_untekked_weapon() {
  537. let mut entity_gateway = InMemoryGateway::default();
  538. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  539. let mut p1_inv = Vec::new();
  540. p1_inv.push(entity_gateway.create_item(
  541. item::NewItemEntity {
  542. item: item::ItemDetail::Weapon(
  543. item::weapon::Weapon {
  544. weapon: item::weapon::WeaponType::Vulcan,
  545. grind: 5,
  546. special: Some(item::weapon::WeaponSpecial::Charge),
  547. attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}),
  548. Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
  549. Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),],
  550. tekked: false,
  551. }
  552. ),
  553. }).await.unwrap());
  554. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  555. let mut ship = Box::new(ShipServerState::builder()
  556. .gateway(entity_gateway.clone())
  557. .build());
  558. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  559. join_lobby(&mut ship, ClientId(1)).await;
  560. create_room(&mut ship, ClientId(1), "room", "").await;
  561. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  562. client: 0,
  563. target: 0,
  564. item_id: 0x10000,
  565. amount: 1,
  566. })))).await.unwrap().for_each(drop);
  567. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  568. assert_eq!(c1_meseta.0, 1);
  569. }
  570. #[async_std::test]
  571. async fn test_player_sells_rare_item() {
  572. let mut entity_gateway = InMemoryGateway::default();
  573. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  574. let mut p1_inv = Vec::new();
  575. p1_inv.push(entity_gateway.create_item(
  576. item::NewItemEntity {
  577. item: item::ItemDetail::Weapon(
  578. item::weapon::Weapon {
  579. weapon: item::weapon::WeaponType::DarkFlow,
  580. grind: 5,
  581. special: None,
  582. attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}),
  583. Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
  584. Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),],
  585. tekked: true,
  586. }
  587. ),
  588. }).await.unwrap());
  589. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  590. let mut ship = Box::new(ShipServerState::builder()
  591. .gateway(entity_gateway.clone())
  592. .build());
  593. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  594. join_lobby(&mut ship, ClientId(1)).await;
  595. create_room(&mut ship, ClientId(1), "room", "").await;
  596. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  597. client: 0,
  598. target: 0,
  599. item_id: 0x10000,
  600. amount: 1,
  601. })))).await.unwrap().for_each(drop);
  602. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  603. assert_eq!(c1_meseta.0, 10);
  604. }
  605. #[async_std::test]
  606. async fn test_player_sells_partial_photon_drop_stack() {
  607. let mut entity_gateway = InMemoryGateway::default();
  608. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  609. let mut p1_inv = Vec::new();
  610. let mut photon_drops = Vec::new();
  611. for _ in 0..7usize {
  612. photon_drops.push(entity_gateway.create_item(
  613. item::NewItemEntity {
  614. item: item::ItemDetail::Tool(
  615. item::tool::Tool {
  616. tool: item::tool::ToolType::PhotonDrop,
  617. }
  618. ),
  619. }).await.unwrap());
  620. }
  621. p1_inv.push(item::InventoryItemEntity::Stacked(photon_drops));
  622. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  623. let mut ship = Box::new(ShipServerState::builder()
  624. .gateway(entity_gateway.clone())
  625. .build());
  626. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  627. join_lobby(&mut ship, ClientId(1)).await;
  628. create_room(&mut ship, ClientId(1), "room", "").await;
  629. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  630. client: 0,
  631. target: 0,
  632. item_id: 0x10000,
  633. amount: 3,
  634. })))).await.unwrap().for_each(drop);
  635. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  636. assert_eq!(c1_meseta.0, 3000);
  637. }
  638. #[async_std::test]
  639. async fn test_player_sells_basic_frame() {
  640. let mut entity_gateway = InMemoryGateway::default();
  641. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  642. let mut p1_inv = Vec::new();
  643. p1_inv.push(entity_gateway.create_item(
  644. item::NewItemEntity {
  645. item: item::ItemDetail::Armor(
  646. item::armor::Armor {
  647. armor: item::armor::ArmorType::Frame,
  648. dfp: 0,
  649. evp: 0,
  650. slots: 0,
  651. }
  652. ),
  653. }).await.unwrap());
  654. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  655. let mut ship = Box::new(ShipServerState::builder()
  656. .gateway(entity_gateway.clone())
  657. .build());
  658. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  659. join_lobby(&mut ship, ClientId(1)).await;
  660. create_room(&mut ship, ClientId(1), "room", "").await;
  661. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  662. client: 0,
  663. target: 0,
  664. item_id: 0x10000,
  665. amount: 1,
  666. })))).await.unwrap().for_each(drop);
  667. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  668. assert_eq!(c1_meseta.0, 24);
  669. }
  670. #[async_std::test]
  671. async fn test_player_sells_max_frame() {
  672. let mut entity_gateway = InMemoryGateway::default();
  673. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  674. let mut p1_inv = Vec::new();
  675. p1_inv.push(entity_gateway.create_item(
  676. item::NewItemEntity {
  677. item: item::ItemDetail::Armor(
  678. item::armor::Armor {
  679. armor: item::armor::ArmorType::Frame,
  680. dfp: 2,
  681. evp: 2,
  682. slots: 4,
  683. }
  684. ),
  685. }).await.unwrap());
  686. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  687. let mut ship = Box::new(ShipServerState::builder()
  688. .gateway(entity_gateway.clone())
  689. .build());
  690. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  691. join_lobby(&mut ship, ClientId(1)).await;
  692. create_room(&mut ship, ClientId(1), "room", "").await;
  693. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  694. client: 0,
  695. target: 0,
  696. item_id: 0x10000,
  697. amount: 1,
  698. })))).await.unwrap().for_each(drop);
  699. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  700. assert_eq!(c1_meseta.0, 74);
  701. }
  702. #[async_std::test]
  703. async fn test_player_sells_basic_barrier() {
  704. let mut entity_gateway = InMemoryGateway::default();
  705. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  706. let mut p1_inv = Vec::new();
  707. p1_inv.push(entity_gateway.create_item(
  708. item::NewItemEntity {
  709. item: item::ItemDetail::Shield(
  710. item::shield::Shield {
  711. shield: item::shield::ShieldType::Barrier,
  712. dfp: 0,
  713. evp: 0,
  714. }
  715. ),
  716. }).await.unwrap());
  717. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  718. let mut ship = Box::new(ShipServerState::builder()
  719. .gateway(entity_gateway.clone())
  720. .build());
  721. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  722. join_lobby(&mut ship, ClientId(1)).await;
  723. create_room(&mut ship, ClientId(1), "room", "").await;
  724. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  725. client: 0,
  726. target: 0,
  727. item_id: 0x10000,
  728. amount: 1,
  729. })))).await.unwrap().for_each(drop);
  730. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  731. assert_eq!(c1_meseta.0, 69);
  732. }
  733. #[async_std::test]
  734. async fn test_player_sells_max_barrier() {
  735. let mut entity_gateway = InMemoryGateway::default();
  736. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  737. let mut p1_inv = Vec::new();
  738. p1_inv.push(entity_gateway.create_item(
  739. item::NewItemEntity {
  740. item: item::ItemDetail::Shield(
  741. item::shield::Shield {
  742. shield: item::shield::ShieldType::Barrier,
  743. dfp: 5,
  744. evp: 5,
  745. }
  746. ),
  747. }).await.unwrap());
  748. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  749. let mut ship = Box::new(ShipServerState::builder()
  750. .gateway(entity_gateway.clone())
  751. .build());
  752. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  753. join_lobby(&mut ship, ClientId(1)).await;
  754. create_room(&mut ship, ClientId(1), "room", "").await;
  755. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  756. client: 0,
  757. target: 0,
  758. item_id: 0x10000,
  759. amount: 1,
  760. })))).await.unwrap().for_each(drop);
  761. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  762. assert_eq!(c1_meseta.0, 122);
  763. }
  764. #[async_std::test]
  765. async fn test_player_sells_1_star_minusminus_unit() {
  766. let mut entity_gateway = InMemoryGateway::default();
  767. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  768. let mut p1_inv = Vec::new();
  769. p1_inv.push(entity_gateway.create_item(
  770. item::NewItemEntity {
  771. item: item::ItemDetail::Unit(
  772. item::unit::Unit {
  773. unit: item::unit::UnitType::PriestMind,
  774. modifier: Some(item::unit::UnitModifier::MinusMinus),
  775. }
  776. ),
  777. }).await.unwrap());
  778. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  779. let mut ship = Box::new(ShipServerState::builder()
  780. .gateway(entity_gateway.clone())
  781. .build());
  782. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  783. join_lobby(&mut ship, ClientId(1)).await;
  784. create_room(&mut ship, ClientId(1), "room", "").await;
  785. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  786. client: 0,
  787. target: 0,
  788. item_id: 0x10000,
  789. amount: 1,
  790. })))).await.unwrap().for_each(drop);
  791. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  792. assert_eq!(c1_meseta.0, 125);
  793. }
  794. #[async_std::test]
  795. async fn test_player_sells_5_star_plusplus_unit() {
  796. let mut entity_gateway = InMemoryGateway::default();
  797. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  798. let mut p1_inv = Vec::new();
  799. p1_inv.push(entity_gateway.create_item(
  800. item::NewItemEntity {
  801. item: item::ItemDetail::Unit(
  802. item::unit::Unit {
  803. unit: item::unit::UnitType::GeneralHp,
  804. modifier: Some(item::unit::UnitModifier::PlusPlus),
  805. }
  806. ),
  807. }).await.unwrap());
  808. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  809. let mut ship = Box::new(ShipServerState::builder()
  810. .gateway(entity_gateway.clone())
  811. .build());
  812. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  813. join_lobby(&mut ship, ClientId(1)).await;
  814. create_room(&mut ship, ClientId(1), "room", "").await;
  815. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  816. client: 0,
  817. target: 0,
  818. item_id: 0x10000,
  819. amount: 1,
  820. })))).await.unwrap().for_each(drop);
  821. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  822. assert_eq!(c1_meseta.0, 625);
  823. }
  824. #[async_std::test]
  825. async fn test_player_sells_rare_frame() {
  826. let mut entity_gateway = InMemoryGateway::default();
  827. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  828. let mut p1_inv = Vec::new();
  829. p1_inv.push(entity_gateway.create_item(
  830. item::NewItemEntity {
  831. item: item::ItemDetail::Armor(
  832. item::armor::Armor {
  833. armor: item::armor::ArmorType::StinkFrame,
  834. dfp: 10,
  835. evp: 20,
  836. slots: 3,
  837. }
  838. ),
  839. }).await.unwrap());
  840. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  841. let mut ship = Box::new(ShipServerState::builder()
  842. .gateway(entity_gateway.clone())
  843. .build());
  844. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  845. join_lobby(&mut ship, ClientId(1)).await;
  846. create_room(&mut ship, ClientId(1), "room", "").await;
  847. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  848. client: 0,
  849. target: 0,
  850. item_id: 0x10000,
  851. amount: 1,
  852. })))).await.unwrap().for_each(drop);
  853. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  854. assert_eq!(c1_meseta.0, 10);
  855. }
  856. #[async_std::test]
  857. async fn test_player_sells_rare_barrier() {
  858. let mut entity_gateway = InMemoryGateway::default();
  859. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  860. let mut p1_inv = Vec::new();
  861. p1_inv.push(entity_gateway.create_item(
  862. item::NewItemEntity {
  863. item: item::ItemDetail::Shield(
  864. item::shield::Shield {
  865. shield: item::shield::ShieldType::RedRing,
  866. dfp: 10,
  867. evp: 20,
  868. }
  869. ),
  870. }).await.unwrap());
  871. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  872. let mut ship = Box::new(ShipServerState::builder()
  873. .gateway(entity_gateway.clone())
  874. .build());
  875. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  876. join_lobby(&mut ship, ClientId(1)).await;
  877. create_room(&mut ship, ClientId(1), "room", "").await;
  878. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  879. client: 0,
  880. target: 0,
  881. item_id: 0x10000,
  882. amount: 1,
  883. })))).await.unwrap().for_each(drop);
  884. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  885. assert_eq!(c1_meseta.0, 10);
  886. }
  887. #[async_std::test]
  888. async fn test_player_sells_rare_unit() {
  889. let mut entity_gateway = InMemoryGateway::default();
  890. let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  891. let mut p1_inv = Vec::new();
  892. p1_inv.push(entity_gateway.create_item(
  893. item::NewItemEntity {
  894. item: item::ItemDetail::Unit(
  895. item::unit::Unit {
  896. unit: item::unit::UnitType::V101,
  897. modifier: None,
  898. }
  899. ),
  900. }).await.unwrap());
  901. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  902. let mut ship = Box::new(ShipServerState::builder()
  903. .gateway(entity_gateway.clone())
  904. .build());
  905. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  906. join_lobby(&mut ship, ClientId(1)).await;
  907. create_room(&mut ship, ClientId(1), "room", "").await;
  908. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  909. client: 0,
  910. target: 0,
  911. item_id: 0x10000,
  912. amount: 1,
  913. })))).await.unwrap().for_each(drop);
  914. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  915. assert_eq!(c1_meseta.0, 10);
  916. }