@@ -18,6 +18,8 @@ public class CDN
1818 // However, if ProductDirectory is accessed before the first CDN is loaded (or if not set through .build.info loading) it'll be null.
1919 public string ProductDirectory = string . Empty ;
2020
21+ public string ArmadilloKeyName = string . Empty ;
22+
2123 // TODO: Memory mapped cache file access?
2224 public CDN ( Settings settings )
2325 {
@@ -213,6 +215,8 @@ public async Task<string> GetPatchServiceFile(string product, string file = "ver
213215
214216 if ( ! string . IsNullOrEmpty ( Settings . CDNDir ) )
215217 {
218+ // TODO: How do we handle encrypted local CDN copies?
219+
216220 var cdnPath = Path . Combine ( Settings . CDNDir , ProductDirectory , type , $ "{ hash [ 0 ] } { hash [ 1 ] } ", $ "{ hash [ 2 ] } { hash [ 3 ] } ", hash ) ;
217221 FileLocks . TryAdd ( cdnPath , new Lock ( ) ) ;
218222
@@ -253,7 +257,25 @@ public async Task<string> GetPatchServiceFile(string product, string file = "ver
253257 {
254258 using ( var fileStream = new FileStream ( cachePath , FileMode . Create , FileAccess . Write ) )
255259 {
256- response . Content . ReadAsStream ( token ) . CopyTo ( fileStream ) ;
260+ if ( string . IsNullOrEmpty ( ArmadilloKeyName ) )
261+ {
262+ response . Content . ReadAsStream ( token ) . CopyTo ( fileStream ) ;
263+ }
264+ else
265+ {
266+ using ( var ms = new MemoryStream ( ) )
267+ {
268+ response . Content . ReadAsStream ( token ) . CopyTo ( ms ) ;
269+ ms . Position = 0 ;
270+ if ( ! BLTE . TryDecryptArmadillo ( hash , ArmadilloKeyName , ms . ToArray ( ) , out var output ) )
271+ {
272+ Console . WriteLine ( "Failed to decrypt file " + hash + " downloaded from " + CDNServers [ i ] ) ;
273+ File . Delete ( cachePath ) ;
274+ continue ;
275+ }
276+ fileStream . Write ( output ) ;
277+ }
278+ }
257279 }
258280 }
259281 catch ( Exception e )
@@ -351,6 +373,8 @@ public unsafe bool TryGetLocalFile(string eKey, out ReadOnlySpan<byte> data)
351373
352374 if ( ! string . IsNullOrEmpty ( Settings . CDNDir ) )
353375 {
376+ // TODO: How do we handle encrypted local CDN copies?
377+
354378 var cdnPath = Path . Combine ( Settings . CDNDir , ProductDirectory , "data" , $ "{ archive [ 0 ] } { archive [ 1 ] } ", $ "{ archive [ 2 ] } { archive [ 3 ] } ", archive ) ;
355379 FileLocks . TryAdd ( cdnPath , new Lock ( ) ) ;
356380 if ( File . Exists ( cdnPath ) )
@@ -416,7 +440,25 @@ public unsafe bool TryGetLocalFile(string eKey, out ReadOnlySpan<byte> data)
416440 {
417441 using ( var fileStream = new FileStream ( cachePath , FileMode . Create , FileAccess . Write ) )
418442 {
419- response . Content . ReadAsStream ( token ) . CopyTo ( fileStream ) ;
443+ if ( string . IsNullOrEmpty ( ArmadilloKeyName ) )
444+ {
445+ response . Content . ReadAsStream ( token ) . CopyTo ( fileStream ) ;
446+ }
447+ else
448+ {
449+ using ( var ms = new MemoryStream ( ) )
450+ {
451+ response . Content . ReadAsStream ( token ) . CopyTo ( ms ) ;
452+ ms . Position = 0 ;
453+ if ( ! BLTE . TryDecryptArmadillo ( archive , ArmadilloKeyName , ms . ToArray ( ) , out var output , offset ) )
454+ {
455+ Console . WriteLine ( "Failed to decrypt file " + eKey + " from archive " + archive + " downloaded from " + CDNServers [ i ] ) ;
456+ File . Delete ( cachePath ) ;
457+ continue ;
458+ }
459+ fileStream . Write ( output ) ;
460+ }
461+ }
420462 }
421463 }
422464 catch ( Exception ex )
@@ -489,5 +531,60 @@ public unsafe bool TryGetLocalFile(string eKey, out ReadOnlySpan<byte> data)
489531
490532 return cachePath ;
491533 }
534+
535+ public string GetProductConfig ( string hash , CancellationToken token = new ( ) )
536+ {
537+ lock ( cdnLock )
538+ {
539+ if ( CDNServers . Count == 0 )
540+ {
541+ LoadCDNs ( ) ;
542+ }
543+ }
544+
545+ var cachePath = Path . Combine ( Settings . CacheDir , "tpr/configs/data" , hash ) ;
546+ FileLocks . TryAdd ( cachePath , new Lock ( ) ) ;
547+
548+ if ( File . Exists ( cachePath ) )
549+ return File . ReadAllText ( cachePath ) ;
550+
551+ for ( var i = 0 ; i < CDNServers . Count ; i ++ )
552+ {
553+ var url = $ "http://{ CDNServers [ i ] } /tpr/configs/data/{ hash [ 0 ] } { hash [ 1 ] } /{ hash [ 2 ] } { hash [ 3 ] } /{ hash } ";
554+
555+ Console . WriteLine ( "Downloading " + url ) ;
556+
557+ var request = new HttpRequestMessage ( HttpMethod . Get , url ) ;
558+
559+ var response = Client . Send ( request , token ) ;
560+
561+ if ( ! response . IsSuccessStatusCode )
562+ {
563+ Console . WriteLine ( "Encountered HTTP " + response . StatusCode + " downloading " + hash + " from " + CDNServers [ i ] ) ;
564+ continue ;
565+ }
566+
567+ lock ( FileLocks [ cachePath ] )
568+ {
569+ Directory . CreateDirectory ( Path . GetDirectoryName ( cachePath ) ! ) ;
570+
571+ try
572+ {
573+ using ( var fileStream = new FileStream ( cachePath , FileMode . Create , FileAccess . Write ) )
574+ response . Content . ReadAsStream ( token ) . CopyTo ( fileStream ) ;
575+ }
576+ catch ( Exception e )
577+ {
578+ Console . WriteLine ( "Failed to download file: " + e . Message ) ;
579+ File . Delete ( cachePath ) ;
580+ continue ;
581+ }
582+ }
583+
584+ return File . ReadAllText ( cachePath ) ;
585+ }
586+
587+ throw new FileNotFoundException ( "Exhausted all CDNs trying to download " + hash ) ;
588+ }
492589 }
493590}
0 commit comments