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.

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