Skip to main content

ddapi_rs/scheme/
ddstats.rs

1use crate::scheme::DDSTATS_BASE_URL;
2use crate::util::prelude::{encode, seconds_to_hours, slugify2};
3use serde::{Deserialize, Serialize};
4
5#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
6pub struct Player {
7    pub points_graph: Vec<PointsGraph>,
8    pub recent_finishes: Vec<RecentFinish>,
9    pub favourite_teammates: Vec<FavouriteTeammate>,
10    pub profile: Profile,
11    pub is_mapper: bool,
12    pub finishes: Vec<Finish>,
13    pub unfinished_maps: Vec<UnfinishedMap>,
14    pub points: Points,
15    #[serde(default)]
16    pub completion_progress: Vec<CompletionProgress>,
17    pub recent_activity: Vec<RecentActivity>,
18    pub recent_player_info: Vec<RecentPlayerInfo>,
19    pub most_played_maps: Vec<MostPlayedMap>,
20    pub most_played_gametypes: Vec<MostPlayed>,
21    pub most_played_categories: Vec<MostPlayed>,
22    pub most_played_locations: Vec<MostPlayed>,
23    pub playtime_per_month: Vec<PlaytimePerMonth>,
24    pub general_activity: Option<GeneralActivity>,
25    pub favourite_rank1s_teammates: Vec<FavouriteRank1sTeammates>,
26    pub all_top_10s: Vec<AllTop10>,
27    pub recent_top_10s: Vec<RecentTop10>,
28}
29
30#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
31pub struct CompletionProgress {
32    pub category: String,
33    pub maps_finished: u64,
34    pub maps_total: u64,
35}
36
37impl Player {
38    pub fn url(&self) -> String {
39        format!(
40            "https://{}/player/{}",
41            DDSTATS_BASE_URL,
42            encode(&self.profile.name)
43        )
44    }
45
46    pub fn url_with_name(player: &str) -> String {
47        format!("https://{}/player/{}", DDSTATS_BASE_URL, encode(player))
48    }
49
50    pub fn api(player: &str) -> String {
51        format!(
52            "https://{}/player/json?player={}",
53            DDSTATS_BASE_URL,
54            encode(player)
55        )
56    }
57}
58
59#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
60pub struct PointsGraph {
61    pub date: String,
62    pub points: i64,
63    pub rank_points: i64,
64    pub team_points: i64,
65}
66
67#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
68pub struct RecentFinish {
69    pub map: StatsMap,
70    pub name: String,
71    pub time: f64,
72    pub timestamp: String,
73    pub server: String,
74    pub cp1: f64,
75    pub cp2: f64,
76    pub cp3: f64,
77    pub cp4: f64,
78    pub cp5: f64,
79    pub cp6: f64,
80    pub cp7: f64,
81    pub cp8: f64,
82    pub cp9: f64,
83    pub cp10: f64,
84    pub cp11: f64,
85    pub cp12: f64,
86    pub cp13: f64,
87    pub cp14: f64,
88    pub cp15: f64,
89    pub cp16: f64,
90    pub cp17: f64,
91    pub cp18: f64,
92    pub cp19: f64,
93    pub cp20: f64,
94    pub cp21: f64,
95    pub cp22: f64,
96    pub cp23: f64,
97    pub cp24: f64,
98    pub cp25: f64,
99}
100
101#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
102pub struct StatsMap {
103    pub map: String,
104    pub server: String,
105    pub points: u8,
106    pub stars: u8,
107    pub mapper: String,
108    pub timestamp: Option<String>,
109}
110
111impl StatsMap {
112    pub fn url(&self) -> String {
113        format!(
114            "https://{}/map/{}",
115            DDSTATS_BASE_URL,
116            encode(&slugify2(&self.map))
117        )
118    }
119
120    pub fn url_with_name(map: &str) -> String {
121        format!(
122            "https://{}/map/{}",
123            DDSTATS_BASE_URL,
124            encode(&slugify2(map))
125        )
126    }
127
128    pub fn api() -> String {
129        format!("https://{}/maps/json", DDSTATS_BASE_URL)
130    }
131}
132
133#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
134pub struct FavouriteTeammate {
135    pub name: String,
136    pub ranks_together: i64,
137}
138
139#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
140pub struct Profile {
141    pub name: String,
142    pub points: i32,
143    pub clan: Option<String>,
144    pub country: Option<i32>,
145    pub skin_name: Option<String>,
146    pub skin_color_body: Option<i32>,
147    pub skin_color_feet: Option<i32>,
148    pub most_played_location: Option<String>,
149}
150
151impl Profile {
152    pub fn url(&self) -> String {
153        format!("https://{}/player/{}", DDSTATS_BASE_URL, encode(&self.name))
154    }
155
156    pub fn url_with_name(player: &str) -> String {
157        format!("https://{}/player/{}", DDSTATS_BASE_URL, encode(player))
158    }
159
160    pub fn api(player: &str) -> String {
161        format!(
162            "https://{}/profile/json?player={}",
163            DDSTATS_BASE_URL,
164            encode(player)
165        )
166    }
167}
168
169#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
170pub struct Finish {
171    pub map: StatsMap,
172    pub name: String,
173    pub time: f64,
174    pub timestamp: String,
175    pub server: String,
176    pub rank: u64,
177    pub team_rank: Option<u64>,
178    pub seconds_played: Option<u64>,
179}
180
181#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
182pub struct UnfinishedMap {
183    pub map: StatsMap,
184    pub finishes: u64,
185    pub finishes_rank: Option<u64>,
186    pub median_time: Option<f64>,
187}
188
189#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
190pub struct Points {
191    pub weekly_points: Option<PPoints>,
192    pub monthly_points: Option<PPoints>,
193    pub yearly_points: Option<PPoints>,
194    pub points: StatsPoints,
195    pub rank_points: StatsPoints,
196    pub team_points: StatsPoints,
197}
198
199#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
200pub struct PPoints {
201    pub points: i64,
202    pub rank: i64,
203}
204
205#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
206#[serde(rename_all = "PascalCase")]
207pub struct StatsPoints {
208    pub moderate: Option<Type>,
209    pub insane: Option<Type>,
210    pub oldschool: Option<Type>,
211    pub fun: Option<Type>,
212    pub race: Option<Type>,
213    pub total: Option<Type>,
214    #[serde(rename = "DDmaX.Easy")]
215    pub ddmax_easy: Option<Type>,
216    pub novice: Option<Type>,
217    pub dummy: Option<Type>,
218    #[serde(rename = "DDmaX.Pro")]
219    pub ddmax_pro: Option<Type>,
220    pub brutal: Option<Type>,
221    #[serde(rename = "DDmaX.Nut")]
222    pub ddmax_nut: Option<Type>,
223    pub solo: Option<Type>,
224    #[serde(rename = "DDmaX.Next")]
225    pub ddmax_next: Option<Type>,
226}
227
228#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
229pub struct Type {
230    pub points: i64,
231    pub rank: i64,
232}
233
234#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
235pub struct RecentActivity {
236    pub name: String,
237    pub date: String,
238    pub map_name: String,
239    pub map: Option<StatsMap>,
240    pub seconds_played: i64,
241}
242
243#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
244pub struct RecentPlayerInfo {
245    pub name: String,
246    pub clan: String,
247    pub country: i32,
248    pub skin_name: Option<String>,
249    pub skin_color_body: Option<u64>,
250    pub skin_color_feet: Option<u64>,
251    pub last_seen: String,
252    pub seconds_played: u64,
253}
254
255#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
256pub struct MostPlayedMap {
257    pub map_name: String,
258    pub seconds_played: u64,
259    pub map: Option<StatsMap>,
260}
261
262#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
263pub struct MostPlayed {
264    pub key: String,
265    pub seconds_played: u64,
266}
267
268#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
269pub struct PlaytimePerMonth {
270    pub year_month: String,
271    pub month: String,
272    pub seconds_played: u64,
273}
274
275#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
276pub struct GeneralActivity {
277    pub total_seconds_played: u64,
278    pub start_of_playtime: String,
279    pub average_seconds_played: u64,
280}
281
282impl GeneralActivity {
283    pub fn total_seconds_played_to_hours(&self) -> f64 {
284        seconds_to_hours(self.total_seconds_played as f64)
285    }
286
287    pub fn average_seconds_played_to_hours(&self) -> f64 {
288        seconds_to_hours(self.average_seconds_played as f64)
289    }
290}
291
292#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
293pub struct FavouriteRank1sTeammates {
294    pub name: String,
295    pub ranks_together: u64,
296}
297
298#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
299pub struct AllTop10 {
300    pub map: StatsMap,
301    pub name: String,
302    pub time: f64,
303    pub rank: u64,
304    pub team_rank: Option<u64>,
305    pub team_time: Option<f64>,
306}
307
308#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
309pub struct RecentTop10 {
310    pub rank_type: String,
311    pub map: String,
312    pub time: f64,
313    pub rank: u64,
314    pub timestamp: String,
315    pub server: String,
316}
317
318#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
319pub struct InfoSMap {
320    pub map: StatsMap,
321    pub finishes: u64,
322    pub finishes_rank: u64,
323    pub median_time: f64,
324}
325
326#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
327pub struct RankingSMap {
328    pub rank: u64,
329    pub timestamp: Option<String>,
330    pub name: String,
331    pub time: f64,
332    pub map: String,
333    pub server: String,
334}
335
336#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
337pub struct TeamRankingSMap {
338    pub rank: u64,
339    pub timestamp: Option<String>,
340    pub id: Vec<u64>,
341    pub players: Vec<String>,
342    pub time: f64,
343    pub map: String,
344    pub server: String,
345}
346
347#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
348pub struct TimeCpsSMap {
349    pub name: String,
350    pub cp1: f64,
351    pub cp2: f64,
352    pub cp3: f64,
353    pub cp4: f64,
354    pub cp5: f64,
355    pub cp6: f64,
356    pub cp7: f64,
357    pub cp8: f64,
358    pub cp9: f64,
359    pub cp10: f64,
360    pub cp11: f64,
361    pub cp12: f64,
362    pub cp13: f64,
363    pub cp14: f64,
364    pub cp15: f64,
365    pub cp16: f64,
366    pub cp17: f64,
367    pub cp18: f64,
368    pub cp19: f64,
369    pub cp20: f64,
370    pub cp21: f64,
371    pub cp22: f64,
372    pub cp23: f64,
373    pub cp24: f64,
374    pub cp25: f64,
375    pub time: f64,
376}
377
378#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
379pub struct PlaytimeSMap {
380    pub name: String,
381    pub seconds_played: u64,
382}
383
384#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
385pub struct Map {
386    pub info: InfoSMap,
387    pub rankings: Vec<RankingSMap>,
388    pub team_rankings: Vec<TeamRankingSMap>,
389    pub time_cps: Vec<TimeCpsSMap>,
390    pub playtime: Vec<PlaytimeSMap>,
391}
392
393impl Map {
394    pub fn url(&self) -> String {
395        format!(
396            "https://{}/map/{}",
397            DDSTATS_BASE_URL,
398            encode(&self.info.map.map)
399        )
400    }
401
402    pub fn url_with_name(map: &str) -> String {
403        format!("https://{}/map/{}", DDSTATS_BASE_URL, encode(map))
404    }
405
406    pub fn api(map: &str) -> String {
407        format!("https://{}/map/json?map={}", DDSTATS_BASE_URL, encode(map))
408    }
409}