@@ -15,20 +15,30 @@ static void Main(string[] layoutPaths)
1515 {
1616 if ( layoutPaths . Count ( ) == 0 )
1717 {
18- Utilities . Log ( new string [ ] { "No layout.json paths specified." , "Usage: MSFSLayoutGenerator.exe <layout.json> ..." } ) ;
18+ Utilities . Log ( new string [ ] { "No layout.json paths specified." , "Usage: MSFSLayoutGenerator.exe <layout.json> ..." } ) ;
1919 }
2020 else
2121 {
22+ //Some serialization options to match layout.json as closely as possible to the MSFS format.
23+ JsonSerializerOptions jsonOptions = new JsonSerializerOptions ( ) ;
24+ jsonOptions . WriteIndented = true ;
25+ jsonOptions . Encoder = System . Text . Encodings . Web . JavaScriptEncoder . Create ( UnicodeRanges . All ) ;
26+
2227 foreach ( string path in layoutPaths )
2328 {
2429 Layout layout = new Layout ( ) ;
30+
31+ //Get absolute path in case we have a relative path.
2532 string layoutPath = Path . GetFullPath ( path ) ;
2633 string json ;
34+ long totalPackageSize = 0 ;
2735
36+ //Ensure that the specified file is named "layout.json".
2837 if ( string . Equals ( Path . GetFileName ( layoutPath ) , "layout.json" , StringComparison . OrdinalIgnoreCase ) )
2938 {
3039 foreach ( string file in Directory . GetFiles ( Path . GetDirectoryName ( layoutPath ) , "*.*" , SearchOption . AllDirectories ) )
3140 {
41+ //Certain .NET APIs don't like long file paths, so we check to ensure the length is under the limit.
3242 if ( file . Length > 259 )
3343 {
3444 Utilities . Log ( "One or more file paths in the folder containing \" " + layoutPath + "\" are 260 characters or greater in length. Please move this package to a directory with a shorter path." ) ;
@@ -40,10 +50,20 @@ static void Main(string[] layoutPaths)
4050 content . Path = relativePath ;
4151 content . Size = new FileInfo ( file ) . Length ;
4252 content . Date = new FileInfo ( file ) . LastWriteTimeUtc . ToFileTimeUtc ( ) ;
43-
53+
54+ //The MSFS virtual file system doesn't need a few select files/folders to be specified in layout.json, so we omit those.
4455 if ( ! relativePath . StartsWith ( "_CVT_" , StringComparison . OrdinalIgnoreCase ) && ! string . Equals ( relativePath , "business.json" ) && ! string . Equals ( relativePath , "layout.json" ) && ! string . Equals ( relativePath , "manifest.json" ) )
4556 {
4657 layout . Content . Add ( content ) ;
58+
59+ //Log the size of each file so we can update total_package_size in manifest.json later if it exists.
60+ totalPackageSize += content . Size ;
61+ }
62+
63+ //The size of these files must be considered for total_package_size as well
64+ if ( string . Equals ( relativePath , "business.json" ) || string . Equals ( relativePath , "manifest.json" ) )
65+ {
66+ totalPackageSize += content . Size ;
4767 }
4868 }
4969
@@ -52,19 +72,54 @@ static void Main(string[] layoutPaths)
5272 Utilities . Log ( "No files were found in the folder containing \" " + layoutPath + "\" . The layout.json will not be updated." ) ;
5373 }
5474
55- JsonSerializerOptions jsonOptions = new JsonSerializerOptions ( ) ;
56- jsonOptions . WriteIndented = true ;
57- jsonOptions . Encoder = System . Text . Encodings . Web . JavaScriptEncoder . Create ( UnicodeRanges . All ) ;
58-
5975 json = JsonSerializer . Serialize ( layout , jsonOptions ) ;
6076
6177 try
6278 {
79+ //Changing new lines to match MSFS format (LF).
6380 File . WriteAllText ( layoutPath , json . Replace ( "\r \n " , "\n " ) ) ;
6481 }
6582 catch ( Exception ex )
6683 {
67- Utilities . Log ( "Error: " + ex . Message ) ;
84+ Utilities . Log ( "Failed to write layout.json: " + ex . Message ) ;
85+ }
86+
87+ //Add layout.json size now that it has been written.
88+ totalPackageSize += new FileInfo ( layoutPath ) . Length ;
89+
90+ //Getting the full path to manifest.json so we can update it.
91+ string manifestPath = Path . Combine ( new string [ ] { Path . GetDirectoryName ( layoutPath ) , "manifest.json" } ) ;
92+
93+ if ( File . Exists ( manifestPath ) )
94+ {
95+ Dictionary < string , object > manifest = new Dictionary < string , object > ( ) ;
96+
97+ try
98+ {
99+ manifest = JsonSerializer . Deserialize < Dictionary < string , object > > ( File . ReadAllText ( manifestPath ) ) ;
100+ }
101+ catch ( Exception ex )
102+ {
103+ Utilities . Log ( "Failed to parse manifest.json: " + ex . Message ) ;
104+ }
105+
106+ //If manifest.json exists and contains the total_package_size property, we update it with the size we collected by iterating through each file for layout.json.
107+ if ( manifest . ContainsKey ( "total_package_size" ) )
108+ {
109+ manifest [ "total_package_size" ] = totalPackageSize . ToString ( ) . PadLeft ( 20 , '0' ) ;
110+
111+ string manifestJson = JsonSerializer . Serialize ( manifest , jsonOptions ) ;
112+
113+ try
114+ {
115+ //Strangly, line endings are different on manifest.json (CRLF)
116+ File . WriteAllText ( manifestPath , manifestJson ) ;
117+ }
118+ catch ( Exception ex )
119+ {
120+ Utilities . Log ( "Failed to write manifest.json: " + ex . Message ) ;
121+ }
122+ }
68123 }
69124 }
70125 else
0 commit comments