11using System . Runtime . InteropServices ;
22using System . Security . Cryptography ;
3+ using System . Text . Json ;
34using System . Text . Json . Nodes ;
45using System . Xml . Linq ;
56using ValveKeyValue ;
@@ -16,15 +17,13 @@ public static async Task<int> Main(string[] args)
1617
1718 AssertPlatformSupported ( ) ;
1819
19- string unturnedPath ;
20- string redistPath ;
2120 if ( args . Length < 3 )
2221 {
2322 Console . WriteLine ( "Wrong usage. Correct usage: UnturnedRedistUpdateTool.exe <unturned_path> <redist_path> <app_id> [args]" ) ;
2423 return 1 ;
2524 }
26- unturnedPath = args [ 0 ] ;
27- redistPath = args [ 1 ] ;
25+ var unturnedPath = args [ 0 ] ;
26+ var redistPath = args [ 1 ] ;
2827 AppId = args [ 2 ] ;
2928 Force = args . Any ( x => x . Equals ( "--force" , StringComparison . OrdinalIgnoreCase ) ) ;
3029
@@ -33,12 +32,12 @@ public static async Task<int> Main(string[] args)
3332 Console . WriteLine ( "AppId is not specified." ) ;
3433 return 1 ;
3534 }
36- if ( Directory . Exists ( unturnedPath ) == false )
35+ if ( ! Directory . Exists ( unturnedPath ) )
3736 {
3837 Console . WriteLine ( $ "Path doesn't exists: \" { unturnedPath } \" .") ;
3938 return 1 ;
4039 }
41- if ( Directory . Exists ( redistPath ) == false )
40+ if ( ! Directory . Exists ( redistPath ) )
4241 {
4342 Console . WriteLine ( $ "Redist path doesn't exists: \" { redistPath } \" .") ;
4443 return 1 ;
@@ -49,7 +48,7 @@ public static async Task<int> Main(string[] args)
4948 Console . WriteLine ( $ ".nuspec file cannot be found in redist folder: \" { redistPath } \" .") ;
5049 return 1 ;
5150 }
52- if ( File . Exists ( nuspecFilePath ) == false )
51+ if ( ! File . Exists ( nuspecFilePath ) )
5352 {
5453 Console . WriteLine ( $ ".nuspec file doesn't exists in redist folder: \" { redistPath } \" .") ;
5554 return 1 ;
@@ -58,21 +57,21 @@ public static async Task<int> Main(string[] args)
5857 Console . WriteLine ( "Preparing to run tool..." ) ;
5958
6059 var steamappsDirectory = Path . Combine ( unturnedPath , "steamapps" ) ;
61- if ( Directory . Exists ( steamappsDirectory ) == false )
60+ if ( ! Directory . Exists ( steamappsDirectory ) )
6261 {
6362 Console . WriteLine ( $ "steamapps Directory not found: \" { steamappsDirectory } \" ") ;
6463 return 1 ;
6564 }
6665 var unturnedDataPath = GetUnturnedDataDirectoryName ( unturnedPath ) ;
6766 var managedDirectory = Path . Combine ( unturnedDataPath , "Managed" ) ;
68- if ( Directory . Exists ( managedDirectory ) == false )
67+ if ( ! Directory . Exists ( managedDirectory ) )
6968 {
7069 Console . WriteLine ( $ "Unturned Managed Directory not found: \" { managedDirectory } \" ") ;
7170 return 1 ;
7271 }
7372 const string statusFileName = "Status.json" ;
7473 var statusFilePath = Path . Combine ( unturnedPath , statusFileName ) ;
75- if ( File . Exists ( statusFilePath ) == false )
74+ if ( ! File . Exists ( statusFilePath ) )
7675 {
7776 throw new FileNotFoundException ( "Status file is not found" , statusFilePath ) ;
7877 }
@@ -99,7 +98,7 @@ public static async Task<int> Main(string[] args)
9998
10099 doc . Save ( nuspecFilePath ) ;
101100
102- var updatedFiles = UpdateRedist ( managedDirectory ) ;
101+ var updatedFiles = await UpdateRedist ( managedDirectory ) ;
103102 if ( updatedFiles . Count == 0 )
104103 {
105104 Console . WriteLine ( $ "No one file were updated, perhaps something went wrong.") ;
@@ -126,28 +125,31 @@ void AssertPlatformSupported()
126125 throw new PlatformNotSupportedException ( ) ;
127126 }
128127 }
129- Dictionary < string , string > UpdateRedist ( string unturnedManagedDirectory )
128+
129+ async Task < Dictionary < string , string > > UpdateRedist ( string unturnedManagedDirectory )
130130 {
131131 var managedFiles = new DirectoryInfo ( unturnedManagedDirectory ) . GetFiles ( ) ;
132132 if ( managedFiles . Length == 0 )
133133 {
134134 throw new InvalidOperationException ( $ "{ unturnedManagedDirectory } directory was empty") ;
135135 }
136136
137- var updatedFiles = new Dictionary < string , string > ( ) ;
137+ Dictionary < string , string > updatedFiles = [ ] ;
138+ Dictionary < string , string > manifest = [ ] ;
138139 foreach ( var fileInfo in managedFiles )
139140 {
140141 try
141142 {
142143 var managedFilePath = fileInfo . FullName ;
143144 var redistFilePath = Path . Combine ( redistPath , fileInfo . Name ) ;
144- if ( File . Exists ( redistFilePath ) == false )
145+ var managedHash = HashHelper . GetFileHash ( managedFilePath ) ;
146+ manifest [ fileInfo . Name ] = managedHash ;
147+ if ( ! File . Exists ( redistFilePath ) )
145148 {
146149 continue ;
147150 }
148- var managedFileData = File . ReadAllBytes ( managedFilePath ) ;
149- var redistFileData = File . ReadAllBytes ( redistFilePath ) ;
150- if ( HashHelper . IsSameHashes ( managedFileData , redistFileData ) )
151+ var redistHash = HashHelper . GetFileHash ( redistFilePath ) ;
152+ if ( managedHash == redistHash )
151153 {
152154 continue ;
153155 }
@@ -161,10 +163,15 @@ Dictionary<string, string> UpdateRedist(string unturnedManagedDirectory)
161163 }
162164 }
163165
166+ var manifestPath = Path . Combine ( redistPath , "manifest.sha256.json" ) ;
167+ await File . WriteAllTextAsync ( manifestPath , JsonSerializer . Serialize ( manifest , ManifestJsonSerializerOptions ) ) ;
168+
164169 return updatedFiles ;
165170 }
166171 }
167172
173+ private static readonly JsonSerializerOptions ManifestJsonSerializerOptions = new ( ) { WriteIndented = true } ;
174+
168175 private static string GetUnturnedDataDirectoryName ( string unturnedPath )
169176 {
170177 const string linuxUnturnedDataDirectoryName = "Unturned_Headless_Data" ;
@@ -188,7 +195,7 @@ private static string GetUnturnedDataDirectoryName(string unturnedPath)
188195
189196 var appmanifestFileName = $ "appmanifest_{ appId } .acf";
190197 var appmanifestFilePath = Path . Combine ( steamappsPath , appmanifestFileName ) ;
191- if ( File . Exists ( appmanifestFilePath ) == false )
198+ if ( ! File . Exists ( appmanifestFilePath ) )
192199 {
193200 throw new FileNotFoundException ( "Required file is not found" , appmanifestFilePath ) ;
194201 }
@@ -204,17 +211,20 @@ private static string GetUnturnedDataDirectoryName(string unturnedPath)
204211
205212internal static class HashHelper
206213{
207- public static string GetHashFromArray ( byte [ ] data )
214+ public static string GetFileHash ( string filePath )
208215 {
209216 using var sha = SHA256 . Create ( ) ;
210- using var input = new MemoryStream ( data ) ;
211- var output = sha . ComputeHash ( input ) ;
212- const string minusSymbol = "-" ;
213- return BitConverter
214- . ToString ( output )
215- . Replace ( minusSymbol , string . Empty )
216- . ToLowerInvariant ( ) ;
217+ using var stream = File . OpenRead ( filePath ) ;
218+ var hash = sha . ComputeHash ( stream ) ;
219+ return Convert . ToHexString ( hash ) . ToLowerInvariant ( ) ;
217220 }
221+
222+ public static string GetHashFromArray ( byte [ ] data )
223+ {
224+ var hash = SHA256 . HashData ( data ) ;
225+ return Convert . ToHexString ( hash ) . ToLowerInvariant ( ) ;
226+ }
227+
218228 public static bool IsSameHashes ( byte [ ] managedFileData , byte [ ] redistFileData )
219229 {
220230 return GetHashFromArray ( managedFileData ) == GetHashFromArray ( redistFileData ) ;
0 commit comments