@@ -4,6 +4,7 @@ use chrono::DateTime;
44use chrono:: Local ;
55use escaper:: decode_html;
66use serde:: Serialize ;
7+ use serde:: Serializer ;
78use wows_replays:: analyzer:: battle_controller:: BattleResult ;
89use wows_replays:: analyzer:: battle_controller:: ChatChannel ;
910use wows_replays:: analyzer:: battle_controller:: GameMessage ;
@@ -20,9 +21,9 @@ use crate::ui::replay_parser::VehicleReport;
2021
2122#[ derive( Serialize ) ]
2223pub struct Match {
23- vehicles : Vec < Vehicle > ,
24- metadata : Metadata ,
25- game_chat : Vec < Message > ,
24+ pub vehicles : Vec < Vehicle > ,
25+ pub metadata : Metadata ,
26+ pub game_chat : Vec < Message > ,
2627}
2728
2829impl Match {
@@ -66,14 +67,6 @@ impl Match {
6667
6768 match_data
6869 }
69-
70- pub fn vehicles ( & self ) -> & [ Vehicle ] {
71- & self . vehicles
72- }
73-
74- pub fn metadata ( & self ) -> & Metadata {
75- & self . metadata
76- }
7770}
7871
7972#[ derive( Serialize ) ]
@@ -124,6 +117,177 @@ impl From<&wows_replays::analyzer::battle_controller::Player> for Player {
124117 }
125118}
126119
120+ fn serialize_option_vec < S > ( opt_vec : & Option < Vec < String > > , serializer : S ) -> Result < S :: Ok , S :: Error >
121+ where
122+ S : Serializer ,
123+ {
124+ match opt_vec {
125+ Some ( vec) => {
126+ let joined = vec. join ( "," ) ;
127+ serializer. serialize_str ( & joined)
128+ }
129+ None => serializer. serialize_none ( ) ,
130+ }
131+ }
132+
133+ #[ derive( Serialize ) ]
134+ pub struct FlattenedVehicle {
135+ player_name : String ,
136+ player_clan : String ,
137+ player_id : i64 ,
138+ player_realm : String ,
139+ /// Ship index that can be mapped to a GameParam
140+ index : String ,
141+ /// Ship name from EN localization
142+ ship_name : String ,
143+ /// Ship nation (e.g. "usa", "pan asia", etc.)
144+ ship_nation : String ,
145+ /// Ship class
146+ ship_class : Species ,
147+ /// Ship tier
148+ ship_tier : u32 ,
149+ /// Whether this is a test ship
150+ is_test_ship : bool ,
151+ /// Whether this is an enemy
152+ is_enemy : bool ,
153+ #[ serde( serialize_with = "serialize_option_vec" ) ]
154+ modules : Option < Vec < String > > ,
155+ #[ serde( serialize_with = "serialize_option_vec" ) ]
156+ abilities : Option < Vec < String > > ,
157+ /// Captain ID that can be mapped to a GameParam
158+ captain_id : Option < String > ,
159+ #[ serde( serialize_with = "serialize_option_vec" ) ]
160+ captain_skills : Option < Vec < String > > ,
161+ xp : Option < i64 > ,
162+ raw_xp : Option < i64 > ,
163+ damage : Option < u64 > ,
164+ ap : Option < u64 > ,
165+ sap : Option < u64 > ,
166+ he : Option < u64 > ,
167+ he_secondaries : Option < u64 > ,
168+ sap_secondaries : Option < u64 > ,
169+ torps : Option < u64 > ,
170+ deep_water_torps : Option < u64 > ,
171+ fire : Option < u64 > ,
172+ flooding : Option < u64 > ,
173+ spotting_damage : Option < u64 > ,
174+ potential_damage : Option < u64 > ,
175+ potential_damage_artillery : Option < u64 > ,
176+ potential_damage_torpedoes : Option < u64 > ,
177+ potential_damage_planes : Option < u64 > ,
178+ received_damage : Option < u64 > ,
179+ received_damage_ap : Option < u64 > ,
180+ received_damage_sap : Option < u64 > ,
181+ received_damage_he : Option < u64 > ,
182+ received_damage_he_secondaries : Option < u64 > ,
183+ received_damage_sap_secondaries : Option < u64 > ,
184+ received_damage_torps : Option < u64 > ,
185+ received_damage_deep_water_torps : Option < u64 > ,
186+ received_damage_fire : Option < u64 > ,
187+ received_damage_flooding : Option < u64 > ,
188+ fires_dealt : Option < u64 > ,
189+ floods_dealt : Option < u64 > ,
190+ citadels_dealt : Option < u64 > ,
191+ crits_dealt : Option < u64 > ,
192+ distance_traveled : Option < f64 > ,
193+ kills : Option < i64 > ,
194+ observed_damage : u64 ,
195+ observed_kills : i64 ,
196+ skill_points_allocated : Option < usize > ,
197+ num_skills : Option < usize > ,
198+ highest_tier_skill : Option < usize > ,
199+ num_tier_1_skills : Option < usize > ,
200+ time_lived_secs : Option < u64 > ,
201+ }
202+
203+ impl From < Vehicle > for FlattenedVehicle {
204+ fn from ( value : Vehicle ) -> Self {
205+ let Vehicle {
206+ player,
207+ index,
208+ name,
209+ nation,
210+ class,
211+ tier,
212+ is_test_ship,
213+ is_enemy,
214+ raw_config : _,
215+ translated_build,
216+ captain_id,
217+ server_results,
218+ observed_results,
219+ skill_meta_info,
220+ time_lived_secs,
221+ } = value;
222+
223+ let ( modules, abilities, captain_skills) = if let Some ( translated_config) = translated_build {
224+ let modules = translated_config. modules . iter ( ) . filter_map ( |module| module. name . clone ( ) ) . collect ( ) ;
225+ let abilities = translated_config. abilities . iter ( ) . filter_map ( |ability| ability. name . clone ( ) ) . collect ( ) ;
226+ let captain_skills = translated_config. captain_skills . map ( |skills| skills. iter ( ) . filter_map ( |skill| skill. name . clone ( ) ) . collect ( ) ) ;
227+ ( Some ( modules) , Some ( abilities) , captain_skills)
228+ } else {
229+ ( None , None , None )
230+ } ;
231+ Self {
232+ player_name : player. name ,
233+ player_clan : player. clan ,
234+ player_id : player. db_id ,
235+ player_realm : player. realm ,
236+ index,
237+ ship_name : name,
238+ ship_nation : nation,
239+ ship_class : class,
240+ ship_tier : tier,
241+ is_test_ship,
242+ is_enemy,
243+ modules,
244+ abilities,
245+ captain_id : Some ( captain_id) ,
246+ captain_skills,
247+ xp : server_results. as_ref ( ) . map ( |results| results. xp ) ,
248+ raw_xp : server_results. as_ref ( ) . map ( |results| results. raw_xp ) ,
249+ damage : server_results. as_ref ( ) . map ( |results| results. damage ) ,
250+ ap : server_results. as_ref ( ) . and_then ( |results| results. damage_details . ap ) ,
251+ sap : server_results. as_ref ( ) . and_then ( |results| results. damage_details . sap ) ,
252+ he : server_results. as_ref ( ) . and_then ( |results| results. damage_details . he ) ,
253+ he_secondaries : server_results. as_ref ( ) . and_then ( |results| results. damage_details . he_secondaries ) ,
254+ sap_secondaries : server_results. as_ref ( ) . and_then ( |results| results. damage_details . sap_secondaries ) ,
255+ torps : server_results. as_ref ( ) . and_then ( |results| results. damage_details . torps ) ,
256+ deep_water_torps : server_results. as_ref ( ) . and_then ( |results| results. damage_details . deep_water_torps ) ,
257+ fire : server_results. as_ref ( ) . and_then ( |results| results. damage_details . fire ) ,
258+ flooding : server_results. as_ref ( ) . and_then ( |results| results. damage_details . flooding ) ,
259+ spotting_damage : server_results. as_ref ( ) . map ( |results| results. spotting_damage ) ,
260+ potential_damage : server_results. as_ref ( ) . map ( |results| results. potential_damage ) ,
261+ potential_damage_artillery : server_results. as_ref ( ) . map ( |results| results. potential_damage_details . artillery ) ,
262+ potential_damage_torpedoes : server_results. as_ref ( ) . map ( |results| results. potential_damage_details . torpedoes ) ,
263+ potential_damage_planes : server_results. as_ref ( ) . map ( |results| results. potential_damage_details . planes ) ,
264+ received_damage : server_results. as_ref ( ) . map ( |results| results. received_damage ) ,
265+ received_damage_ap : server_results. as_ref ( ) . and_then ( |results| results. received_damage_details . ap ) ,
266+ received_damage_sap : server_results. as_ref ( ) . and_then ( |results| results. received_damage_details . sap ) ,
267+ received_damage_he : server_results. as_ref ( ) . and_then ( |results| results. received_damage_details . he ) ,
268+ received_damage_he_secondaries : server_results. as_ref ( ) . and_then ( |results| results. received_damage_details . he_secondaries ) ,
269+ received_damage_sap_secondaries : server_results. as_ref ( ) . and_then ( |results| results. received_damage_details . sap_secondaries ) ,
270+ received_damage_torps : server_results. as_ref ( ) . and_then ( |results| results. received_damage_details . torps ) ,
271+ received_damage_deep_water_torps : server_results. as_ref ( ) . and_then ( |results| results. received_damage_details . deep_water_torps ) ,
272+ received_damage_fire : server_results. as_ref ( ) . and_then ( |results| results. received_damage_details . fire ) ,
273+ received_damage_flooding : server_results. as_ref ( ) . and_then ( |results| results. received_damage_details . flooding ) ,
274+ fires_dealt : server_results. as_ref ( ) . map ( |results| results. fires_dealt ) ,
275+ floods_dealt : server_results. as_ref ( ) . map ( |results| results. floods_dealt ) ,
276+ citadels_dealt : server_results. as_ref ( ) . map ( |results| results. citadels_dealt ) ,
277+ crits_dealt : server_results. as_ref ( ) . map ( |results| results. crits_dealt ) ,
278+ distance_traveled : server_results. as_ref ( ) . map ( |results| results. distance_traveled ) ,
279+ kills : server_results. as_ref ( ) . map ( |results| results. kills ) ,
280+ observed_damage : observed_results. as_ref ( ) . map ( |results| results. damage ) . unwrap_or_default ( ) ,
281+ observed_kills : observed_results. as_ref ( ) . map ( |results| results. kills ) . unwrap_or_default ( ) ,
282+ skill_points_allocated : skill_meta_info. as_ref ( ) . map ( |info| info. skill_points ) ,
283+ num_skills : skill_meta_info. as_ref ( ) . map ( |info| info. num_skills ) ,
284+ highest_tier_skill : skill_meta_info. as_ref ( ) . map ( |info| info. highest_tier ) ,
285+ num_tier_1_skills : skill_meta_info. as_ref ( ) . map ( |info| info. num_tier_1_skills ) ,
286+ time_lived_secs,
287+ }
288+ }
289+ }
290+
127291#[ derive( Serialize ) ]
128292pub struct Vehicle {
129293 player : Player ,
0 commit comments