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 api(player: &str) -> String {
127        format!("https://ddstats.tw/profile/json?player={}", encode(player))
128    }
129}
130
131#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
132pub struct Finish {
133    pub map: StatsMap,
134    pub name: String,
135    pub time: f64,
136    pub timestamp: String,
137    pub server: String,
138    pub rank: u64,
139    pub team_rank: Option<u64>,
140    pub seconds_played: Option<u64>,
141}
142
143#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
144pub struct UnfinishedMap {
145    pub map: StatsMap,
146    pub finishes: u64,
147    pub finishes_rank: Option<u64>,
148    pub median_time: Option<f64>,
149}
150
151#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
152pub struct Points {
153    pub weekly_points: Option<PPoints>,
154    pub monthly_points: Option<PPoints>,
155    pub yearly_points: Option<PPoints>,
156    pub points: StatsPoints,
157    pub rank_points: StatsPoints,
158    pub team_points: StatsPoints,
159}
160
161#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
162pub struct PPoints {
163    pub points: i64,
164    pub rank: i64,
165}
166
167#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
168#[serde(rename_all = "PascalCase")]
169pub struct StatsPoints {
170    pub moderate: Option<Type>,
171    pub insane: Option<Type>,
172    pub oldschool: Option<Type>,
173    pub fun: Option<Type>,
174    pub race: Option<Type>,
175    pub total: Option<Type>,
176    #[serde(rename = "DDmaX.Easy")]
177    pub ddmax_easy: Option<Type>,
178    pub novice: Option<Type>,
179    pub dummy: Option<Type>,
180    #[serde(rename = "DDmaX.Pro")]
181    pub ddmax_pro: Option<Type>,
182    pub brutal: Option<Type>,
183    #[serde(rename = "DDmaX.Nut")]
184    pub ddmax_nut: Option<Type>,
185    pub solo: Option<Type>,
186    #[serde(rename = "DDmaX.Next")]
187    pub ddmax_next: Option<Type>,
188}
189
190#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
191pub struct Type {
192    pub points: i64,
193    pub rank: i64,
194}
195
196#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
197pub struct RecentActivity {
198    pub name: String,
199    pub date: String,
200    pub map_name: String,
201    pub map: Option<StatsMap>,
202    pub seconds_played: i64,
203}
204
205#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
206pub struct RecentPlayerInfo {
207    pub name: String,
208    pub clan: String,
209    pub country: i16,
210    pub skin_name: Option<String>,
211    pub skin_color_body: Option<u64>,
212    pub skin_color_feet: Option<u64>,
213    pub last_seen: String,
214    pub seconds_played: u64,
215}
216
217#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
218pub struct MostPlayedMap {
219    pub map_name: String,
220    pub seconds_played: u64,
221    pub map: Option<StatsMap>,
222}
223
224#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
225pub struct MostPlayed {
226    pub key: String,
227    pub seconds_played: u64,
228}
229
230#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
231pub struct PlaytimePerMonth {
232    pub year_month: String,
233    pub month: String,
234    pub seconds_played: u64,
235}
236
237#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
238pub struct GeneralActivity {
239    pub total_seconds_played: u64,
240    pub start_of_playtime: String,
241    pub average_seconds_played: u64,
242}
243
244impl GeneralActivity {
245    pub fn total_seconds_played_to_hours(&self) -> f64 {
246        seconds_to_hours(self.total_seconds_played)
247    }
248
249    pub fn average_seconds_played_to_hours(&self) -> f64 {
250        seconds_to_hours(self.average_seconds_played)
251    }
252}
253
254#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
255pub struct FavouriteRank1sTeammates {
256    pub name: String,
257    pub ranks_together: u64,
258}
259
260#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
261pub struct AllTop10 {
262    pub map: StatsMap,
263    pub name: String,
264    pub time: f64,
265    pub rank: u64,
266    pub team_rank: Option<u64>,
267    pub team_time: Option<f64>,
268}
269
270#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
271pub struct RecentTop10 {
272    pub rank_type: String,
273    pub map: String,
274    pub time: f64,
275    pub rank: u64,
276    pub timestamp: String,
277    pub server: String,
278}
279
280#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
281pub struct InfoSMap {
282    pub map: StatsMap,
283    pub finishes: u64,
284    pub finishes_rank: u64,
285    pub median_time: f64,
286}
287
288#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
289pub struct RankingSMap {
290    pub rank: u64,
291    pub timestamp: Option<String>,
292    pub name: String,
293    pub time: f64,
294    pub map: String,
295    pub server: String,
296}
297
298#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
299pub struct TeamRankingSMap {
300    pub rank: u64,
301    pub timestamp: Option<String>,
302    pub id: Vec<u64>,
303    pub players: Vec<String>,
304    pub time: f64,
305    pub map: String,
306    pub server: String,
307}
308
309#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
310pub struct TimeCpsSMap {
311    pub name: String,
312    pub cp1: f64,
313    pub cp2: f64,
314    pub cp3: f64,
315    pub cp4: f64,
316    pub cp5: f64,
317    pub cp6: f64,
318    pub cp7: f64,
319    pub cp8: f64,
320    pub cp9: f64,
321    pub cp10: f64,
322    pub cp11: f64,
323    pub cp12: f64,
324    pub cp13: f64,
325    pub cp14: f64,
326    pub cp15: f64,
327    pub cp16: f64,
328    pub cp17: f64,
329    pub cp18: f64,
330    pub cp19: f64,
331    pub cp20: f64,
332    pub cp21: f64,
333    pub cp22: f64,
334    pub cp23: f64,
335    pub cp24: f64,
336    pub cp25: f64,
337    pub time: f64,
338}
339
340#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
341pub struct PlaytimeSMap {
342    pub name: String,
343    pub seconds_played: u64,
344}
345
346#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
347pub struct Map {
348    pub info: InfoSMap,
349    pub rankings: Vec<RankingSMap>,
350    pub team_rankings: Vec<TeamRankingSMap>,
351    pub time_cps: Vec<TimeCpsSMap>,
352    pub playtime: Vec<PlaytimeSMap>,
353}
354
355impl Map {
356    pub fn api(map: &str) -> String {
357        format!("https://ddstats.tw/map/json?map={}", encode(map))
358    }
359}