robloxapi_s/games/
mod.rs

1pub mod models;
2
3use self::models::{DevProduct, Game, Server};
4use crate::ApiResult;
5
6use async_trait::async_trait;
7use reqwest::Method;
8
9#[async_trait]
10pub trait GameBuilder {
11    async fn new(self, client: &mut crate::Https) -> ApiResult<Game>;
12}
13
14#[async_trait]
15impl GameBuilder for u64 {
16    async fn new(self: u64, client: &mut crate::Https) -> ApiResult<Game> {
17        let udata: _ = client
18            .request::<serde_json::Value>(
19                Method::GET,
20                &format!(
21                    "{}/games/multiget-place-details?placeIds={}",
22                    crate::GAMES,
23                    self
24                ),
25            )
26            .await
27            .expect("Failed to get game universe info");
28
29        let fdata = client
30            .request::<serde_json::Value>(
31                Method::GET,
32                &format!(
33                    "{}/games?universeIds={}",
34                    crate::GAMES,
35                    udata[0]
36                        .get("universeId")
37                        .expect("Failed to find game universe ID")
38                ),
39            )
40            .await
41            .expect("Failed to get game root info");
42
43        Ok(Game {
44            client: client.clone(),
45            ..serde_json::from_value(
46                fdata.get("data").expect("Failed to get game root data")[0].clone(),
47            )
48            .expect("Failed to parse into Game")
49        })
50        // client.request::<Game>(Method::GET,
51        //     &format!(
52        //         "{}/games/multiget-place-details?placeIds={}",
53        //         crate::GAMES,
54        //         self
55        //     )).await
56    }
57}
58
59impl Game {
60    /// Get a list of servers from the Game
61    /// # Example
62    /// ```
63    ///
64    /// #[tokio::main]
65    /// async fn main() {
66    ///     
67    ///     // Place ID
68    ///     let game_id = 7415484311;
69    ///     let mut client = robloxapi::Client::new();
70    ///     // List of servers
71    ///     let servers = client.game(game_id)
72    ///         .await
73    ///         .unwrap()
74    ///         .servers();
75    /// }
76    ///
77    /// ```
78    pub async fn servers(&mut self) -> Vec<Server> {
79        if let Some(servers) = self.servers.clone() {
80            servers
81        } else {
82            let mut servers: Vec<Server> = vec![];
83            let mut data = self
84                .client
85                .request::<serde_json::Value>(
86                    Method::GET,
87                    &format!(
88                        "{}/games/{}/servers/Public?limit=100",
89                        crate::GAMES,
90                        self.place_id
91                    ),
92                )
93                .await
94                .expect("Failed to get server list");
95
96            while let Some(cursor) = data.clone().get("nextPageCursor") {
97                if cursor.is_null() {
98                    break;
99                }
100
101                if let Some(info) = data.get("data") {
102                    let data_servers: Vec<Server> =
103                        serde_json::from_value(info.clone()).unwrap_or_default();
104                    servers.extend_from_slice(&data_servers[..]);
105                }
106
107                data = self
108                    .client
109                    .request(
110                        Method::GET,
111                        &format!(
112                            "{}/games/{}/servers/Public?limit=100&cursor={}",
113                            crate::GAMES,
114                            self.place_id,
115                            cursor.as_str().unwrap()
116                        ),
117                    )
118                    .await
119                    .expect("Failed to get server list");
120
121                if let Some(error) = data.get("errors") {
122                    if let Some(message) = error[0].get("message") {
123                        if message.as_str().unwrap() == "TooManyRequests" {
124                            println!("Rate limited, sleeping for 3 seconds");
125                            tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
126
127                            data = self
128                                .client
129                                .request(
130                                    Method::GET,
131                                    &format!(
132                                        "{}/games/{}/servers/Public?limit=100&cursor={}",
133                                        crate::GAMES,
134                                        self.place_id,
135                                        cursor.as_str().unwrap()
136                                    ),
137                                )
138                                .await
139                                .expect("Failed to get server list");
140                        }
141                    }
142
143                    continue;
144                }
145            }
146
147            self.servers = Some(servers.clone());
148            servers
149        }
150    }
151
152    /// Create a developer product given name and price.
153    /// # Example
154    /// ```
155    /// #[tokio::main]
156    /// async fn main() {
157    ///     let mut client = robloxapi::Client::new();
158    ///     client.set_cookie(COOKIE).await;
159    ///
160    ///     // Create a new game with place id 100000
161    ///     let mut game = client.game(100000).await.unwrap();
162    ///      // Requires client to be logged in with a cookie
163    ///     match game.create_dev_product(
164    ///         "devproduct1", // Name of the devproduct
165    ///         500, // Price of the devproduct
166    ///     ).await {
167    ///         Err(_err) => {
168    ///             todo!() // Handle the error
169    ///         }
170    ///         Ok(dev_product) => {
171    ///             todo!() // Use the DevProduct
172    ///         }
173    ///     };
174    /// }
175    /// ```
176    ///
177    pub async fn create_dev_product(&mut self, name: &str, price: u32) -> ApiResult<DevProduct> {
178        // Make Request To DeveloperProducts
179        self.client
180            .request::<DevProduct>(
181                Method::POST,
182                &format!(
183                    "{}/{}/developerproducts?name={}&description={}&priceInRobux={}",
184                    crate::DEVPAGE,
185                    self.universe_id,
186                    name,
187                    name,
188                    price
189                ),
190            )
191            .await
192    }
193}