ddapi_rs/scheme/
ddstats.rs

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