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}