An unofficial collection of APIs used in FreeJam games and mods
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.

257 lines
7.8KB

  1. use reqwest::{RequestBuilder, Error};
  2. use num_enum::{TryFromPrimitive};
  3. use crate::robocraft::{FactoryInfo, RoboShopItemsInfo};
  4. use crate::robocraft::factory_json::ListPayload;
  5. /// Factory list response ordering
  6. #[derive(Eq, PartialEq, TryFromPrimitive)]
  7. #[repr(u8)]
  8. pub enum FactoryOrderType {
  9. /// Suggested (default)
  10. Suggested = 0,
  11. /// Combat rating (decreasing?)
  12. CombatRating = 1,
  13. /// Cosmetic rating (decreasing?)
  14. CosmeticRating = 2,
  15. /// Date added (oldest first?)
  16. Added = 3,
  17. /// CPU value (decreasing?)
  18. CPU = 4,
  19. /// Purchases (decreasing)
  20. MostBought = 5,
  21. }
  22. /// Robot movement categories
  23. #[derive(Eq, PartialEq, TryFromPrimitive)]
  24. #[repr(u32)]
  25. pub enum FactoryMovementType {
  26. /// Vrooooom
  27. Wheels = 100000,
  28. /// Woooooosh
  29. Hovers = 200000,
  30. /// Fwoooosh
  31. Aerofoils=300000,
  32. /// Also fwoooosh (but actually a different movement type, trust me)
  33. Thrusters=400000,
  34. /// Also also fwoooosh (but also a different movement type)
  35. Rudders=500000,
  36. /// Ewwww
  37. InsectLegs=600000,
  38. /// Mechs are cool
  39. MechLegs=700000,
  40. /// Skis and turning skis
  41. Skis=800000,
  42. /// All tank treads
  43. TankTreads=900000,
  44. /// Wrrrrrrrrrr
  45. Rotors=1000000,
  46. /// Mech legs, but faster
  47. Sprinters=1100000,
  48. /// Wrrrrr but for Fwoooosh
  49. Propellers=1200000
  50. }
  51. /// Robot weapon categories
  52. #[derive(Eq, PartialEq, TryFromPrimitive)]
  53. #[repr(u32)]
  54. pub enum FactoryWeaponType {
  55. /// All laser weapons (aka Lasor, SMG)
  56. Laser=10000000,
  57. /// All plasma launcher weapons
  58. PlasmaLauncher=20000000,
  59. /// Mortar
  60. GyroMortar=25000000,
  61. /// All rails
  62. RailCannon=30000000,
  63. /// All healing weapons
  64. NanoDisruptor=40000000,
  65. /// All tesla blade melee weapons
  66. TeslaBlade=50000000,
  67. /// All aeroflak weapons
  68. AeroflakCannon=60000000,
  69. /// All shotgun weapons
  70. IonCannon=65000000,
  71. /// Lol
  72. ProtoSeeker=70100000,
  73. /// All chain weapons
  74. ChainShredder=75000000,
  75. }
  76. /// Text field search modes
  77. #[derive(Eq, PartialEq, TryFromPrimitive)]
  78. #[repr(u8)]
  79. pub enum FactoryTextSearchType {
  80. /// Search players and robot names
  81. All=0,
  82. /// Search players only
  83. Player=1,
  84. /// Search robot names only
  85. Name=2,
  86. }
  87. /// Factory API list query builder
  88. pub struct FactorySearchBuilder {
  89. reqwest_builder: RequestBuilder,
  90. payload: ListPayload,
  91. token: Option<String>,
  92. }
  93. impl FactorySearchBuilder {
  94. pub(crate) fn new(request_builder: RequestBuilder, token: Option<String>) -> FactorySearchBuilder {
  95. FactorySearchBuilder {
  96. reqwest_builder: request_builder,
  97. payload: ListPayload::empty(),
  98. token,
  99. }
  100. }
  101. /// Retrieve list page page_number
  102. pub fn page(mut self, page_number: isize) -> Self {
  103. self.payload.page = page_number;
  104. self
  105. }
  106. /// Retrieve page_size items per page (this is unreliable)
  107. pub fn items_per_page(mut self, page_size: isize) -> Self {
  108. self.payload.page_size = page_size;
  109. self
  110. }
  111. /// Order list by order_type
  112. pub fn order(mut self, order_type: FactoryOrderType) -> Self {
  113. self.payload.order = order_type as isize;
  114. self
  115. }
  116. /* // this appears to not do anything (removed to prevent confusion)
  117. // use text_search_type(FactoryTextSearchType::Player) instead
  118. pub fn players_only(mut self, p: bool) -> Self {
  119. self.payload.player_filter = p;
  120. self
  121. }
  122. */
  123. /// Retrieve items with movement type.
  124. ///
  125. /// Multiple calls to this function will cause logical OR behaviour.
  126. /// e.g. results will contain robots with Wheels OR Aerofoils (or both).
  127. pub fn movement_or(mut self, movement_type: FactoryMovementType) -> Self {
  128. if self.payload.movement_filter == "" {
  129. self.payload.movement_filter = format!("{},{}", &self.payload.movement_filter, movement_type as isize);
  130. } else {
  131. self.payload.movement_filter = (movement_type as isize).to_string();
  132. }
  133. self.payload.movement_category_filter = self.payload.movement_filter.clone();
  134. self
  135. }
  136. /// Override allowed movement types
  137. pub fn movement_raw(mut self, filter: String) -> Self {
  138. self.payload.movement_filter = filter.clone();
  139. self.payload.movement_category_filter = filter.clone();
  140. self
  141. }
  142. /// Retrieve items with weapon type.
  143. ///
  144. /// Multiple calls to this function will cause logical OR behaviour.
  145. /// e.g. results will contain robots with ChainShredder OR GyroMortar (or both).
  146. pub fn weapon_or(mut self, weapon_type: FactoryWeaponType) -> Self {
  147. if self.payload.weapon_filter == "" {
  148. self.payload.weapon_filter = format!("{},{}", &self.payload.weapon_filter, weapon_type as isize);
  149. } else {
  150. self.payload.weapon_filter = (weapon_type as isize).to_string();
  151. }
  152. self.payload.weapon_category_filter = self.payload.weapon_filter.clone();
  153. self
  154. }
  155. /// Override allowed weapon types
  156. pub fn weapon_raw(mut self, filter: String) -> Self {
  157. self.payload.weapon_filter = filter.clone();
  158. self.payload.weapon_category_filter = filter.clone();
  159. self
  160. }
  161. /// Retrieve items within the specified CPU min and max values
  162. pub fn cpu_range(mut self, min: isize, max: isize) -> Self {
  163. self.payload.minimum_cpu = min;
  164. self.payload.maximum_cpu = max;
  165. self
  166. }
  167. /// Retrieve items with CPU no lower than min
  168. /// overrides cpu_range()
  169. pub fn min_cpu(mut self, min: isize) -> Self {
  170. self.payload.minimum_cpu = min;
  171. self
  172. }
  173. /// Retrieve items with CPU no greater than max
  174. /// overrides cpu_range()
  175. pub fn max_cpu(mut self, max: isize) -> Self {
  176. self.payload.maximum_cpu = max;
  177. self
  178. }
  179. /// Retrieve items with any minimum CPU
  180. pub fn no_minimum_cpu(mut self) -> Self {
  181. self.payload.minimum_cpu = -1;
  182. self
  183. }
  184. /// Retrieve items with any maximum CPU
  185. pub fn no_maximum_cpu(mut self) -> Self {
  186. self.payload.maximum_cpu = -1;
  187. self
  188. }
  189. /// Retrieve items which match text
  190. pub fn text(mut self, t: String) -> Self {
  191. self.payload.text_filter = t;
  192. self
  193. }
  194. /// Text filter searches search_type
  195. pub fn text_search_type(mut self, search_type: FactoryTextSearchType) -> Self {
  196. self.payload.text_search_field = search_type as isize;
  197. self
  198. }
  199. // setting buyable to false while using the default token provider will cause HTTP status 500 error
  200. /// Retrieve only items which are buyable for current account? (default: false)
  201. /// Buyable means that the account owns all blocks required.
  202. /// This will cause an error when using DEFAULT_TOKEN
  203. pub fn buyable(mut self, b: bool) -> Self {
  204. self.payload.buyable = b;
  205. self
  206. }
  207. /// Retrieve items with featured robot at start? (default: false)
  208. pub fn prepend_featured(mut self, b: bool) -> Self {
  209. self.payload.prepend_featured_robot = b;
  210. self
  211. }
  212. /// Retrieve default robot list? (default: false)
  213. /// The default page is the CRF landing page (I think?)
  214. pub fn default_page(mut self, b: bool) -> Self {
  215. self.payload.default_page = b;
  216. self
  217. }
  218. /// Execute list query
  219. pub async fn send(mut self) -> Result<FactoryInfo<RoboShopItemsInfo>, Error> {
  220. self.reqwest_builder = self.reqwest_builder.json(&self.payload);
  221. if let Some(token) = self.token.clone() {
  222. self.reqwest_builder = self.reqwest_builder.header("Authorization", "Web ".to_owned() + &token);
  223. }
  224. let result = self.reqwest_builder.send().await;
  225. if let Ok(response) = result {
  226. return response.json::<FactoryInfo<RoboShopItemsInfo>>().await;
  227. }
  228. Err(result.err().unwrap())
  229. }
  230. }