@@ -7,7 +7,7 @@ use schema::{instance::{InstanceConfiguration, LwjglLibraryPath}, loader::Loader
77use serde:: Deserialize ;
88use uuid:: Uuid ;
99
10- use crate :: { BackendState , account:: BackendAccount } ;
10+ use crate :: { BackendState , account:: BackendAccount , instance :: InstanceStats } ;
1111
1212
1313#[ derive( Deserialize ) ]
@@ -21,6 +21,59 @@ struct MMCPackComponent {
2121 version : Arc < str > ,
2222}
2323
24+ fn try_load_stats_from_multimc ( instance_cfg : & Path ) -> Option < InstanceStats > {
25+ let instance_cfg_str = std:: fs:: read_to_string ( instance_cfg) . ok ( ) ?;
26+
27+ let mut stats = InstanceStats :: default ( ) ;
28+
29+ let mut section = None ;
30+ for line in instance_cfg_str. split ( |v| v == '\n' ) {
31+ let line = line. trim_ascii_start ( ) ;
32+ if line. is_empty ( ) {
33+ continue ;
34+ }
35+
36+ let start = line. as_bytes ( ) [ 0 ] ;
37+ match start {
38+ b';' | b'#' => continue ,
39+ b'[' => {
40+ section = Some ( line. trim_ascii_end ( ) ) ;
41+ } ,
42+ _ => {
43+ let Some ( ( key, value) ) = line. split_once ( "=" ) else {
44+ continue ;
45+ } ;
46+
47+
48+ let mut value = value. trim_ascii ( ) ;
49+ if value. len ( ) > 1 && value. starts_with ( '"' ) && value. ends_with ( '"' ) {
50+ value = & value[ 1 ..value. len ( ) -1 ] ;
51+ } else if value. len ( ) > 1 && value. starts_with ( '\'' ) && value. ends_with ( '\'' ) {
52+ value = & value[ 1 ..value. len ( ) -1 ] ;
53+ }
54+
55+ match ( section, key) {
56+ ( Some ( "[General]" ) , "totalTimePlayed" ) => {
57+ let Ok ( time_played) = value. parse :: < u64 > ( ) else {
58+ continue ;
59+ } ;
60+ stats. total_playtime_secs = time_played;
61+ } ,
62+ ( Some ( "[General]" ) , "lastLaunchTime" ) => {
63+ let Ok ( last_launcher_time) = value. parse :: < i64 > ( ) else {
64+ continue ;
65+ } ;
66+ stats. last_played_unix_ms = Some ( last_launcher_time) ;
67+ }
68+ _ => { }
69+ }
70+ }
71+ }
72+ }
73+
74+ Some ( stats)
75+ }
76+
2477pub fn try_load_from_multimc ( instance_cfg : & Path , mmc_pack : & Path ) -> Option < InstanceConfiguration > {
2578 let mmc_pack_bytes = std:: fs:: read ( mmc_pack) . ok ( ) ?;
2679 let instance_cfg_str = std:: fs:: read_to_string ( instance_cfg) . ok ( ) ?;
@@ -201,7 +254,6 @@ pub fn try_load_from_multimc(instance_cfg: &Path, mmc_pack: &Path) -> Option<Ins
201254 Some ( configuration)
202255}
203256
204-
205257#[ derive( Deserialize , Debug ) ]
206258struct MultiMCAccountsJson {
207259 accounts : Vec < MultiMCAccount >
@@ -479,6 +531,14 @@ fn import_instances_from_multimc(backend: &BackendState, import_job: &ImportFrom
479531 let info_path = to_import. pandora_path . join ( "info_v1.json" ) ;
480532 _ = crate :: write_safe ( & info_path, & configuration_bytes) ;
481533
534+ // Write stats_v1.json if we have stats in the first place.
535+ if let Some ( stats) = try_load_stats_from_multimc ( & to_import. multimc_instance_cfg ) {
536+ let stats_path = to_import. pandora_path . join ( "stats_v1.json" ) ;
537+ if let Ok ( stats_bytes) = serde_json:: to_vec ( & stats) {
538+ _ = crate :: write_safe ( & stats_path, & stats_bytes) ;
539+ }
540+ }
541+
482542 all_tracker. add_count ( 1 ) ;
483543 all_tracker. notify ( ) ;
484544
0 commit comments