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