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.

1053 lines
37 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
3 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
3 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
3 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
3 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
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
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
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
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
  1. use networking::serverstate::{ClientId, ServerState};
  2. use entity::gateway::{EntityGateway, InMemoryGateway};
  3. use entity::item;
  4. use libpso::item::weapon;
  5. use ship_server::{RecvShipPacket, SendShipPacket};
  6. use maps::room::Difficulty;
  7. use items::state::ItemStateError;
  8. use shops::StandardItemShops;
  9. use libpso::packet::ship::*;
  10. use libpso::packet::messages::*;
  11. #[path = "common.rs"]
  12. mod common;
  13. use common::*;
  14. #[async_std::test]
  15. async fn test_player_opens_weapon_shop() {
  16. let mut entity_gateway = InMemoryGateway::default();
  17. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  18. char1.exp = 80000000;
  19. entity_gateway.save_character(&char1).await.unwrap();
  20. let mut ship = standard_ship_buildable(entity_gateway.clone())
  21. .item_shops(StandardItemShops::default())
  22. .build();
  23. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  24. join_lobby(&mut ship, ClientId(1)).await;
  25. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  26. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  27. client: 255,
  28. target: 255,
  29. shop_type: 1
  30. })))).await.unwrap();
  31. assert_eq!(packets.len(), 1);
  32. match &packets[0].1 {
  33. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  34. assert_eq!(shop_list.items.len(), 16)
  35. }
  36. _ => panic!("")
  37. }
  38. }
  39. #[async_std::test]
  40. async fn test_player_opens_tool_shop() {
  41. let mut entity_gateway = InMemoryGateway::default();
  42. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  43. char1.exp = 80000000;
  44. entity_gateway.save_character(&char1).await.unwrap();
  45. let mut ship = standard_ship_buildable(entity_gateway.clone())
  46. .item_shops(StandardItemShops::default())
  47. .build();
  48. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  49. join_lobby(&mut ship, ClientId(1)).await;
  50. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  51. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  52. client: 255,
  53. target: 255,
  54. shop_type: 0
  55. })))).await.unwrap();
  56. assert_eq!(packets.len(), 1);
  57. match &packets[0].1 {
  58. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  59. assert_eq!(shop_list.items.len(), 18)
  60. }
  61. _ => panic!("")
  62. }
  63. }
  64. #[async_std::test]
  65. async fn test_player_opens_armor_shop() {
  66. let mut entity_gateway = InMemoryGateway::default();
  67. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  68. char1.exp = 80000000;
  69. entity_gateway.save_character(&char1).await.unwrap();
  70. let mut ship = standard_ship_buildable(entity_gateway.clone())
  71. .item_shops(StandardItemShops::default())
  72. .build();
  73. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  74. join_lobby(&mut ship, ClientId(1)).await;
  75. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  76. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  77. client: 255,
  78. target: 255,
  79. shop_type: 2
  80. })))).await.unwrap();
  81. assert_eq!(packets.len(), 1);
  82. match &packets[0].1 {
  83. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  84. assert_eq!(shop_list.items.len(), 21)
  85. }
  86. _ => panic!("")
  87. }
  88. }
  89. #[async_std::test]
  90. async fn test_player_buys_from_weapon_shop() {
  91. let mut entity_gateway = InMemoryGateway::default();
  92. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  93. char1.exp = 80000000;
  94. entity_gateway.save_character(&char1).await.unwrap();
  95. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  96. let mut ship = standard_ship_buildable(entity_gateway.clone())
  97. .item_shops(StandardItemShops::default())
  98. .build();
  99. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  100. join_lobby(&mut ship, ClientId(1)).await;
  101. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  102. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  103. client: 255,
  104. target: 255,
  105. shop_type: 1
  106. })))).await.unwrap();
  107. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  108. client: 255,
  109. target: 255,
  110. item_id: 0x10000,
  111. shop_type: 1,
  112. shop_index: 0,
  113. amount: 1,
  114. unknown1: 0,
  115. })))).await.unwrap();
  116. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  117. assert!(c1_meseta.0 < 999999);
  118. //let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap();
  119. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  120. assert_eq!(p1_items.items.len(), 1);
  121. }
  122. #[async_std::test]
  123. async fn test_player_buys_from_tool_shop() {
  124. let mut entity_gateway = InMemoryGateway::default();
  125. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  126. char1.exp = 80000000;
  127. entity_gateway.save_character(&char1).await.unwrap();
  128. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  129. let mut ship = standard_ship_buildable(entity_gateway.clone())
  130. .item_shops(StandardItemShops::default())
  131. .build();
  132. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  133. join_lobby(&mut ship, ClientId(1)).await;
  134. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  135. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  136. client: 255,
  137. target: 255,
  138. shop_type: 0,
  139. })))).await.unwrap();
  140. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  141. client: 255,
  142. target: 255,
  143. item_id: 0x10000,
  144. shop_type: 0,
  145. shop_index: 0,
  146. amount: 1,
  147. unknown1: 0,
  148. })))).await.unwrap();
  149. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  150. assert!(c1_meseta.0 < 999999);
  151. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  152. assert_eq!(p1_items.items.len(), 1);
  153. }
  154. #[async_std::test]
  155. async fn test_player_buys_multiple_from_tool_shop() {
  156. let mut entity_gateway = InMemoryGateway::default();
  157. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  158. char1.exp = 80000000;
  159. entity_gateway.save_character(&char1).await.unwrap();
  160. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  161. let mut ship = standard_ship_buildable(entity_gateway.clone())
  162. .item_shops(StandardItemShops::default())
  163. .build();
  164. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  165. join_lobby(&mut ship, ClientId(1)).await;
  166. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  167. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  168. client: 255,
  169. target: 255,
  170. shop_type: 0,
  171. })))).await.unwrap();
  172. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  173. client: 255,
  174. target: 255,
  175. item_id: 0x10000,
  176. shop_type: 0,
  177. shop_index: 0,
  178. amount: 5,
  179. unknown1: 0,
  180. })))).await.unwrap();
  181. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  182. assert_eq!(c1_meseta.0, 999749);
  183. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  184. assert_eq!(p1_items.items.len(), 1);
  185. p1_items.items[0].with_stacked(|item| {
  186. assert_eq!(item.len(), 5);
  187. assert_eq!(item[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Monomate));
  188. }).unwrap();
  189. }
  190. #[async_std::test]
  191. async fn test_player_buys_from_armor_shop() {
  192. let mut entity_gateway = InMemoryGateway::default();
  193. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  194. char1.exp = 80000000;
  195. entity_gateway.save_character(&char1).await.unwrap();
  196. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  197. let mut ship = standard_ship_buildable(entity_gateway.clone())
  198. .item_shops(StandardItemShops::default())
  199. .build();
  200. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  201. join_lobby(&mut ship, ClientId(1)).await;
  202. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  203. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  204. client: 255,
  205. target: 255,
  206. shop_type: 2
  207. })))).await.unwrap();
  208. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  209. client: 255,
  210. target: 255,
  211. item_id: 0x10000,
  212. shop_type: 2,
  213. shop_index: 0,
  214. amount: 1,
  215. unknown1: 0,
  216. })))).await.unwrap();
  217. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  218. assert!(c1_meseta.0 < 999999);
  219. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  220. assert_eq!(p1_items.items.len(), 1);
  221. }
  222. #[async_std::test]
  223. async fn test_player_sells_3_attr_weapon_to_shop() {
  224. let mut entity_gateway = InMemoryGateway::default();
  225. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  226. let mut p1_inv = Vec::new();
  227. p1_inv.push(entity_gateway.create_item(
  228. ItemBuilder::weapon(weapon::WeaponType::Vulcan)
  229. .grind(5)
  230. .special(weapon::WeaponSpecial::Charge)
  231. .attr(weapon::Attribute::Hit, 100)
  232. .attr(weapon::Attribute::Dark, 100)
  233. .attr(weapon::Attribute::Native, 100)
  234. .as_new()
  235. ).await.unwrap());
  236. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  237. let mut ship = standard_ship(entity_gateway.clone());
  238. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  239. join_lobby(&mut ship, ClientId(1)).await;
  240. create_room(&mut ship, ClientId(1), "room", "").await;
  241. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  242. client: 0,
  243. target: 0,
  244. item_id: 0x10000,
  245. amount: 1,
  246. })))).await.unwrap();
  247. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  248. assert_eq!(c1_meseta.0, 4406);
  249. }
  250. #[async_std::test]
  251. async fn test_other_clients_see_purchase() {
  252. let mut entity_gateway = InMemoryGateway::default();
  253. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  254. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  255. char1.exp = 80000000;
  256. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  257. entity_gateway.save_character(&char1).await.unwrap();
  258. let mut ship = standard_ship_buildable(entity_gateway.clone())
  259. .item_shops(StandardItemShops::default())
  260. .build();
  261. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  262. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  263. join_lobby(&mut ship, ClientId(1)).await;
  264. join_lobby(&mut ship, ClientId(2)).await;
  265. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Normal).await;
  266. join_room(&mut ship, ClientId(2), 0).await;
  267. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  268. client: 255,
  269. target: 255,
  270. shop_type: 1
  271. })))).await.unwrap();
  272. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  273. client: 255,
  274. target: 255,
  275. item_id: 0x10000,
  276. shop_type: 1,
  277. shop_index: 0,
  278. amount: 1,
  279. unknown1: 0,
  280. })))).await.unwrap();
  281. assert_eq!(packets.len(), 1);
  282. assert_eq!(packets[0].0, ClientId(2));
  283. match &packets[0].1 {
  284. SendShipPacket::Message(Message{msg: GameMessage::CreateItem(_)}) => {},
  285. _ => panic!(""),
  286. }
  287. }
  288. #[async_std::test]
  289. async fn test_other_clients_see_stacked_purchase() {
  290. let mut entity_gateway = InMemoryGateway::default();
  291. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  292. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  293. char1.exp = 80000000;
  294. entity_gateway.save_character(&char1).await.unwrap();
  295. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  296. entity_gateway.create_item(
  297. ItemBuilder::tool(item::tool::ToolType::Monomate)
  298. .as_new()
  299. ).await.unwrap();
  300. let mut ship = standard_ship_buildable(entity_gateway.clone())
  301. .item_shops(StandardItemShops::default())
  302. .build();
  303. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  304. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  305. join_lobby(&mut ship, ClientId(1)).await;
  306. join_lobby(&mut ship, ClientId(2)).await;
  307. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Normal).await;
  308. join_room(&mut ship, ClientId(2), 0).await;
  309. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  310. client: 255,
  311. target: 255,
  312. shop_type: 1
  313. })))).await.unwrap();
  314. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  315. client: 255,
  316. target: 255,
  317. item_id: 0x10000,
  318. shop_type: 1,
  319. shop_index: 0,
  320. amount: 1,
  321. unknown1: 0,
  322. })))).await.unwrap();
  323. assert_eq!(packets.len(), 1);
  324. assert_eq!(packets[0].0, ClientId(2));
  325. match &packets[0].1 {
  326. SendShipPacket::Message(Message{msg: GameMessage::CreateItem(_)}) => {},
  327. _ => panic!(""),
  328. }
  329. }
  330. #[async_std::test]
  331. async fn test_buying_item_without_enough_mseseta() {
  332. let mut entity_gateway = InMemoryGateway::default();
  333. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  334. let mut ship = standard_ship(entity_gateway.clone());
  335. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  336. join_lobby(&mut ship, ClientId(1)).await;
  337. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Normal).await;
  338. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  339. client: 255,
  340. target: 255,
  341. shop_type: 1
  342. })))).await.unwrap();
  343. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  344. client: 255,
  345. target: 255,
  346. item_id: 0x10000,
  347. shop_type: 1,
  348. shop_index: 0,
  349. amount: 1,
  350. unknown1: 0,
  351. })))).await;
  352. assert!(packets.is_err());
  353. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  354. assert_eq!(c1_meseta.0, 0);
  355. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  356. assert_eq!(p1_items.items.len(), 0);
  357. }
  358. #[async_std::test]
  359. async fn test_player_double_buys_from_tool_shop() {
  360. let mut entity_gateway = InMemoryGateway::default();
  361. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  362. char1.exp = 80000000;
  363. entity_gateway.save_character(&char1).await.unwrap();
  364. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  365. let mut ship = standard_ship_buildable(entity_gateway.clone())
  366. .item_shops(StandardItemShops::default())
  367. .build();
  368. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  369. join_lobby(&mut ship, ClientId(1)).await;
  370. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  371. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  372. client: 255,
  373. target: 255,
  374. shop_type: 0,
  375. })))).await.unwrap();
  376. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  377. client: 255,
  378. target: 255,
  379. item_id: 0x10000,
  380. shop_type: 0,
  381. shop_index: 0,
  382. amount: 3,
  383. unknown1: 0,
  384. })))).await.unwrap();
  385. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  386. client: 255,
  387. target: 255,
  388. item_id: 0x10001,
  389. shop_type: 0,
  390. shop_index: 1,
  391. amount: 2,
  392. unknown1: 0,
  393. })))).await.unwrap();
  394. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  395. client: 255,
  396. target: 255,
  397. item_id: 0x10002,
  398. shop_type: 0,
  399. shop_index: 0,
  400. amount: 4,
  401. unknown1: 0,
  402. })))).await.unwrap();
  403. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  404. assert!(c1_meseta.0 < 999999);
  405. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  406. assert_eq!(p1_items.items.len(), 2);
  407. p1_items.items[0].with_stacked(|item| {
  408. assert_eq!(item.len(), 7);
  409. assert_eq!(item[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Monomate));
  410. }).unwrap();
  411. p1_items.items[1].with_stacked(|item| {
  412. assert_eq!(item.len(), 2);
  413. assert_eq!(item[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Dimate));
  414. }).unwrap();
  415. }
  416. #[async_std::test]
  417. async fn test_techs_disappear_from_shop_when_bought() {
  418. let mut entity_gateway = InMemoryGateway::default();
  419. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  420. char1.exp = 80000000;
  421. entity_gateway.save_character(&char1).await.unwrap();
  422. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  423. let mut ship = standard_ship_buildable(entity_gateway.clone())
  424. .item_shops(StandardItemShops::default())
  425. .build();
  426. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  427. join_lobby(&mut ship, ClientId(1)).await;
  428. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  429. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  430. client: 255,
  431. target: 255,
  432. shop_type: 0,
  433. })))).await.unwrap();
  434. let first_tech = match &packets[0].1 {
  435. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  436. shop_list.items.iter()
  437. .enumerate()
  438. .filter(|(_, item)| {
  439. item.item_bytes[0] == 3 && item.item_bytes[1] == 2
  440. })
  441. .nth(0).unwrap().0
  442. },
  443. _ => panic!(""),
  444. };
  445. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  446. client: 255,
  447. target: 255,
  448. item_id: 0x10000,
  449. shop_type: 0,
  450. shop_index: first_tech as u8,
  451. amount: 1,
  452. unknown1: 0,
  453. })))).await.unwrap();
  454. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  455. client: 255,
  456. target: 255,
  457. item_id: 0x10001,
  458. shop_type: 0,
  459. shop_index: first_tech as u8,
  460. amount: 1,
  461. unknown1: 0,
  462. })))).await.unwrap();
  463. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  464. p1_items.items[0].with_individual(|item1| {
  465. p1_items.items[1].with_individual(|item2| {
  466. assert_ne!(item1, item2);
  467. }).unwrap();
  468. }).unwrap();
  469. }
  470. // TOOD: this is not deterministic and can randomly fail
  471. #[async_std::test]
  472. async fn test_units_disappear_from_shop_when_bought() {
  473. let mut entity_gateway = InMemoryGateway::default();
  474. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  475. char1.exp = 80000000;
  476. entity_gateway.save_character(&char1).await.unwrap();
  477. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  478. let mut ship = standard_ship_buildable(entity_gateway.clone())
  479. .item_shops(StandardItemShops::default())
  480. .build();
  481. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  482. join_lobby(&mut ship, ClientId(1)).await;
  483. create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  484. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest {
  485. client: 255,
  486. target: 255,
  487. shop_type: 2,
  488. })))).await.unwrap();
  489. let first_unit = match &packets[0].1 {
  490. SendShipPacket::Message(Message {msg: GameMessage::ShopList(shop_list)}) => {
  491. shop_list.items.iter()
  492. .enumerate()
  493. .filter(|(_, item)| {
  494. item.item_bytes[0] == 1 && item.item_bytes[1] == 3
  495. })
  496. .nth(0).unwrap().0
  497. },
  498. _ => panic!(""),
  499. };
  500. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  501. client: 255,
  502. target: 255,
  503. item_id: 0x10000,
  504. shop_type: 2,
  505. shop_index: first_unit as u8,
  506. amount: 1,
  507. unknown1: 0,
  508. })))).await.unwrap();
  509. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BuyItem(BuyItem {
  510. client: 255,
  511. target: 255,
  512. item_id: 0x10001,
  513. shop_type: 2,
  514. shop_index: first_unit as u8,
  515. amount: 1,
  516. unknown1: 0,
  517. })))).await.unwrap();
  518. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  519. p1_items.items[0].with_individual(|item1| {
  520. p1_items.items[1].with_individual(|item2| {
  521. assert_ne!(item1, item2);
  522. }).unwrap();
  523. }).unwrap();
  524. }
  525. #[async_std::test]
  526. async fn test_player_sells_untekked_weapon() {
  527. let mut entity_gateway = InMemoryGateway::default();
  528. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  529. let mut p1_inv = Vec::new();
  530. p1_inv.push(entity_gateway.create_item(
  531. ItemBuilder::weapon(weapon::WeaponType::Vulcan)
  532. .untekked()
  533. .grind(5)
  534. .special(weapon::WeaponSpecial::Charge)
  535. .attr(weapon::Attribute::Hit, 100)
  536. .attr(weapon::Attribute::Dark, 100)
  537. .attr(weapon::Attribute::Native, 100)
  538. .as_new()
  539. ).await.unwrap());
  540. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  541. let mut ship = standard_ship(entity_gateway.clone());
  542. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  543. join_lobby(&mut ship, ClientId(1)).await;
  544. create_room(&mut ship, ClientId(1), "room", "").await;
  545. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  546. client: 0,
  547. target: 0,
  548. item_id: 0x10000,
  549. amount: 1,
  550. })))).await.unwrap();
  551. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  552. assert_eq!(c1_meseta.0, 1);
  553. }
  554. #[async_std::test]
  555. async fn test_player_sells_rare_item() {
  556. let mut entity_gateway = InMemoryGateway::default();
  557. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  558. let mut p1_inv = Vec::new();
  559. p1_inv.push(entity_gateway.create_item(
  560. ItemBuilder::weapon(weapon::WeaponType::DarkFlow)
  561. .grind(5)
  562. .attr(weapon::Attribute::Hit, 100)
  563. .attr(weapon::Attribute::Dark, 100)
  564. .attr(weapon::Attribute::Native, 100)
  565. .as_new()
  566. ).await.unwrap());
  567. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  568. let mut ship = standard_ship(entity_gateway.clone());
  569. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  570. join_lobby(&mut ship, ClientId(1)).await;
  571. create_room(&mut ship, ClientId(1), "room", "").await;
  572. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  573. client: 0,
  574. target: 0,
  575. item_id: 0x10000,
  576. amount: 1,
  577. })))).await.unwrap();
  578. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  579. assert_eq!(c1_meseta.0, 10);
  580. }
  581. #[async_std::test]
  582. async fn test_player_sells_partial_photon_drop_stack() {
  583. let mut entity_gateway = InMemoryGateway::default();
  584. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  585. let mut p1_inv = Vec::new();
  586. let mut photon_drops = Vec::new();
  587. for _ in 0..7usize {
  588. photon_drops.push(entity_gateway.create_item(
  589. ItemBuilder::tool(item::tool::ToolType::PhotonDrop)
  590. .as_new()
  591. ).await.unwrap());
  592. }
  593. p1_inv.push(item::InventoryItemEntity::Stacked(photon_drops));
  594. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  595. let mut ship = standard_ship(entity_gateway.clone());
  596. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  597. join_lobby(&mut ship, ClientId(1)).await;
  598. create_room(&mut ship, ClientId(1), "room", "").await;
  599. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  600. client: 0,
  601. target: 0,
  602. item_id: 0x10000,
  603. amount: 3,
  604. })))).await.unwrap();
  605. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  606. assert_eq!(c1_meseta.0, 3000);
  607. }
  608. #[async_std::test]
  609. async fn test_player_sells_basic_frame() {
  610. let mut entity_gateway = InMemoryGateway::default();
  611. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  612. let mut p1_inv = Vec::new();
  613. p1_inv.push(entity_gateway.create_item(
  614. ItemBuilder::armor(item::armor::ArmorType::Frame)
  615. .as_new()
  616. ).await.unwrap());
  617. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  618. let mut ship = standard_ship(entity_gateway.clone());
  619. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  620. join_lobby(&mut ship, ClientId(1)).await;
  621. create_room(&mut ship, ClientId(1), "room", "").await;
  622. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  623. client: 0,
  624. target: 0,
  625. item_id: 0x10000,
  626. amount: 1,
  627. })))).await.unwrap();
  628. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  629. assert_eq!(c1_meseta.0, 24);
  630. }
  631. #[async_std::test]
  632. async fn test_player_sells_max_frame() {
  633. let mut entity_gateway = InMemoryGateway::default();
  634. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  635. let mut p1_inv = Vec::new();
  636. p1_inv.push(entity_gateway.create_item(
  637. ItemBuilder::armor(item::armor::ArmorType::Frame)
  638. .dfp(2)
  639. .evp(2)
  640. .slots(4)
  641. .as_new()
  642. ).await.unwrap());
  643. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  644. let mut ship = standard_ship(entity_gateway.clone());
  645. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  646. join_lobby(&mut ship, ClientId(1)).await;
  647. create_room(&mut ship, ClientId(1), "room", "").await;
  648. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  649. client: 0,
  650. target: 0,
  651. item_id: 0x10000,
  652. amount: 1,
  653. })))).await.unwrap();
  654. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  655. assert_eq!(c1_meseta.0, 74);
  656. }
  657. #[async_std::test]
  658. async fn test_player_sells_basic_barrier() {
  659. let mut entity_gateway = InMemoryGateway::default();
  660. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  661. let mut p1_inv = Vec::new();
  662. p1_inv.push(entity_gateway.create_item(
  663. ItemBuilder::shield(item::shield::ShieldType::Barrier)
  664. .as_new()
  665. ).await.unwrap());
  666. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  667. let mut ship = standard_ship(entity_gateway.clone());
  668. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  669. join_lobby(&mut ship, ClientId(1)).await;
  670. create_room(&mut ship, ClientId(1), "room", "").await;
  671. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  672. client: 0,
  673. target: 0,
  674. item_id: 0x10000,
  675. amount: 1,
  676. })))).await.unwrap();
  677. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  678. assert_eq!(c1_meseta.0, 69);
  679. }
  680. #[async_std::test]
  681. async fn test_player_sells_max_barrier() {
  682. let mut entity_gateway = InMemoryGateway::default();
  683. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  684. let mut p1_inv = Vec::new();
  685. p1_inv.push(entity_gateway.create_item(
  686. ItemBuilder::shield(item::shield::ShieldType::Barrier)
  687. .dfp(5)
  688. .evp(5)
  689. .as_new()
  690. ).await.unwrap());
  691. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  692. let mut ship = standard_ship(entity_gateway.clone());
  693. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  694. join_lobby(&mut ship, ClientId(1)).await;
  695. create_room(&mut ship, ClientId(1), "room", "").await;
  696. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  697. client: 0,
  698. target: 0,
  699. item_id: 0x10000,
  700. amount: 1,
  701. })))).await.unwrap();
  702. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  703. assert_eq!(c1_meseta.0, 122);
  704. }
  705. #[async_std::test]
  706. async fn test_player_sells_1_star_minusminus_unit() {
  707. let mut entity_gateway = InMemoryGateway::default();
  708. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  709. let mut p1_inv = Vec::new();
  710. p1_inv.push(entity_gateway.create_item(
  711. ItemBuilder::unit(item::unit::UnitType::PriestMind)
  712. .modifier(item::unit::UnitModifier::MinusMinus)
  713. .as_new()
  714. ).await.unwrap());
  715. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  716. let mut ship = standard_ship(entity_gateway.clone());
  717. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  718. join_lobby(&mut ship, ClientId(1)).await;
  719. create_room(&mut ship, ClientId(1), "room", "").await;
  720. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  721. client: 0,
  722. target: 0,
  723. item_id: 0x10000,
  724. amount: 1,
  725. })))).await.unwrap();
  726. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  727. assert_eq!(c1_meseta.0, 125);
  728. }
  729. #[async_std::test]
  730. async fn test_player_sells_5_star_plusplus_unit() {
  731. let mut entity_gateway = InMemoryGateway::default();
  732. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  733. let mut p1_inv = Vec::new();
  734. p1_inv.push(entity_gateway.create_item(
  735. ItemBuilder::unit(item::unit::UnitType::GeneralHp)
  736. .modifier(item::unit::UnitModifier::PlusPlus)
  737. .as_new()
  738. ).await.unwrap());
  739. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  740. let mut ship = standard_ship(entity_gateway.clone());
  741. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  742. join_lobby(&mut ship, ClientId(1)).await;
  743. create_room(&mut ship, ClientId(1), "room", "").await;
  744. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  745. client: 0,
  746. target: 0,
  747. item_id: 0x10000,
  748. amount: 1,
  749. })))).await.unwrap();
  750. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  751. assert_eq!(c1_meseta.0, 625);
  752. }
  753. #[async_std::test]
  754. async fn test_player_sells_rare_frame() {
  755. let mut entity_gateway = InMemoryGateway::default();
  756. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  757. let mut p1_inv = Vec::new();
  758. p1_inv.push(entity_gateway.create_item(
  759. ItemBuilder::armor(item::armor::ArmorType::StinkFrame)
  760. .dfp(10)
  761. .evp(20)
  762. .slots(3)
  763. .as_new()
  764. ).await.unwrap());
  765. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  766. let mut ship = standard_ship(entity_gateway.clone());
  767. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  768. join_lobby(&mut ship, ClientId(1)).await;
  769. create_room(&mut ship, ClientId(1), "room", "").await;
  770. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  771. client: 0,
  772. target: 0,
  773. item_id: 0x10000,
  774. amount: 1,
  775. })))).await.unwrap();
  776. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  777. assert_eq!(c1_meseta.0, 10);
  778. }
  779. #[async_std::test]
  780. async fn test_player_sells_rare_barrier() {
  781. let mut entity_gateway = InMemoryGateway::default();
  782. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  783. let mut p1_inv = Vec::new();
  784. p1_inv.push(entity_gateway.create_item(
  785. ItemBuilder::shield(item::shield::ShieldType::RedRing)
  786. .dfp(10)
  787. .evp(20)
  788. .as_new()
  789. ).await.unwrap());
  790. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  791. let mut ship = standard_ship(entity_gateway.clone());
  792. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  793. join_lobby(&mut ship, ClientId(1)).await;
  794. create_room(&mut ship, ClientId(1), "room", "").await;
  795. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  796. client: 0,
  797. target: 0,
  798. item_id: 0x10000,
  799. amount: 1,
  800. })))).await.unwrap();
  801. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  802. assert_eq!(c1_meseta.0, 10);
  803. }
  804. #[async_std::test]
  805. async fn test_player_sells_rare_unit() {
  806. let mut entity_gateway = InMemoryGateway::default();
  807. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  808. let mut p1_inv = Vec::new();
  809. p1_inv.push(entity_gateway.create_item(
  810. ItemBuilder::unit(item::unit::UnitType::V101)
  811. .as_new()
  812. ).await.unwrap());
  813. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  814. let mut ship = standard_ship(entity_gateway.clone());
  815. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  816. join_lobby(&mut ship, ClientId(1)).await;
  817. create_room(&mut ship, ClientId(1), "room", "").await;
  818. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  819. client: 0,
  820. target: 0,
  821. item_id: 0x10000,
  822. amount: 1,
  823. })))).await.unwrap();
  824. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  825. assert_eq!(c1_meseta.0, 10);
  826. }
  827. #[async_std::test]
  828. async fn test_player_cant_sell_if_meseta_would_go_over_max() {
  829. let mut entity_gateway = InMemoryGateway::default();
  830. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  831. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999995)).await.unwrap();
  832. let mut p1_inv = Vec::new();
  833. p1_inv.push(entity_gateway.create_item(
  834. ItemBuilder::unit(item::unit::UnitType::V101)
  835. .as_new()
  836. ).await.unwrap());
  837. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  838. let mut ship = standard_ship(entity_gateway.clone());
  839. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  840. join_lobby(&mut ship, ClientId(1)).await;
  841. create_room(&mut ship, ClientId(1), "room", "").await;
  842. let ack = ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem {
  843. client: 0,
  844. target: 0,
  845. item_id: 0x10000,
  846. amount: 1,
  847. })))).await.err().unwrap();
  848. //assert_eq!(ack, ShipError::ItemStateError(ItemStateError::FullOfMeseta));
  849. assert!(matches!(ack.downcast::<ItemStateError>().unwrap(), ItemStateError::FullOfMeseta));
  850. //assert!(matches!(ack.downcast::<ShipError>().unwrap(), ShipError::ItemStateError(ItemStateError::FullOfMeseta)));
  851. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  852. assert_eq!(c1_meseta.0, 999995);
  853. }