1+ using System . Collections . Generic ;
2+ using System . Diagnostics ;
3+ using System . IO ;
4+ using System . IO . Compression ;
5+ using System . Linq ;
6+ using System . Text . Json ;
7+ using ComputerUtils . Logging ;
8+ using DiffCreator ;
9+
10+ namespace QuestAppVersionSwitcher . DiffDowngrading
11+ {
12+ public class DiffCreator
13+ {
14+ public static DiffDowngradeEntry CreateDiff ( string sourceBackup , string targetBackup ,
15+ string outputDir )
16+ {
17+ DiffDowngradeEntry baseEntry = new DiffDowngradeEntry ( ) ;
18+ if ( ! sourceBackup . EndsWith ( Path . DirectorySeparatorChar ) ) sourceBackup += Path . DirectorySeparatorChar ;
19+ if ( ! targetBackup . EndsWith ( Path . DirectorySeparatorChar ) ) targetBackup += Path . DirectorySeparatorChar ;
20+ if ( ! outputDir . EndsWith ( Path . DirectorySeparatorChar ) ) outputDir += Path . DirectorySeparatorChar ;
21+ if ( ! Directory . Exists ( targetBackup ) ) Directory . CreateDirectory ( targetBackup ) ;
22+
23+ Logger . Log ( "Creating diff" ) ;
24+ if ( ! File . Exists ( sourceBackup + "app.apk" ) || ! File . Exists ( targetBackup + "app.apk" ) )
25+ {
26+ Logger . Log ( "App.apk not found in source or target backup" ) ;
27+ return null ;
28+ }
29+
30+ PatchingStatus sPatching = Apkutils . GetPatchingStatus ( ZipFile . OpenRead ( sourceBackup + "app.apk" ) ) ;
31+ baseEntry . SV = sPatching . version ;
32+ baseEntry . appid = sPatching . package ;
33+ baseEntry . TV = Apkutils . GetPatchingStatus ( ZipFile . OpenRead ( targetBackup + "app.apk" ) ) . version ;
34+ baseEntry . isXDelta3 = true ;
35+
36+ // Create entries
37+ baseEntry . Set ( CreateDiffOfFile ( baseEntry , sourceBackup + "app.apk" , targetBackup + "app.apk" , outputDir ) ) ;
38+ // add obbs and other files
39+ List < string > allSourceFiles = new List < string > ( ) ;
40+ List < string > allTargetFiles = new List < string > ( ) ;
41+ if ( Directory . Exists ( sourceBackup + "/obb" ) )
42+ {
43+ allSourceFiles = Directory . GetFiles ( sourceBackup + "/obb" ) . ToList ( ) ;
44+ allSourceFiles . Insert ( 0 , sourceBackup + "app.apk" ) ;
45+ }
46+
47+ if ( Directory . Exists ( targetBackup + "/obb" ) )
48+ {
49+ allTargetFiles = Directory . GetFiles ( targetBackup + "/obb" ) . ToList ( ) ;
50+ allTargetFiles . Insert ( 0 , targetBackup + "app.apk" ) ;
51+ }
52+
53+ for ( int i = 1 ; i < allTargetFiles . Count ; i ++ )
54+ {
55+ // generate one diff for every target backup obbs
56+ baseEntry . otherFiles . Add ( CreateDiffOfFile ( baseEntry , allSourceFiles [ i % allSourceFiles . Count ] ,
57+ allTargetFiles [ i ] , outputDir ) ) ;
58+ }
59+
60+ // The diff file is now created
61+ Logger . Log ( "Writing version.json file" ) ;
62+ File . WriteAllText ( outputDir + "version.json" , JsonSerializer . Serialize ( baseEntry ) ) ;
63+ Logger . Log ( "Finished creating diff" ) ;
64+ Logger . Log ( "\n \n Summary:" ) ;
65+ Logger . Log ( "Diff for " + baseEntry . SV + " (apk) -> " + baseEntry . TV + " (apk) created" ) ;
66+ foreach ( FileDiffDowngradeEntry otherFile in baseEntry . otherFiles )
67+ {
68+ Logger . Log ( "Diff for " + otherFile . sourceFilename + " -> " + otherFile . outputFilename + " created" ) ;
69+ }
70+ return baseEntry ;
71+ }
72+
73+ public static FileDiffDowngradeEntry CreateDiffOfFile ( DiffDowngradeEntry baseEntry , string sourcePath ,
74+ string targetPath ,
75+ string outputPath )
76+ {
77+ FileDiffDowngradeEntry e = new FileDiffDowngradeEntry ( ) ;
78+ e . sourceFilename = Path . GetFileName ( sourcePath ) ;
79+ e . outputFilename = Path . GetFileName ( targetPath ) ;
80+ e . diffFilename = baseEntry . GetDowngradeBaseName ( ) + e . sourceFilename + ".xdelta3" ;
81+ e . type = e . sourceFilename . ToLower ( ) . EndsWith ( ".apk" )
82+ ? FileDiffDowngradeEntryType . Apk
83+ : FileDiffDowngradeEntryType . Obb ;
84+ e . isXDelta3 = true ;
85+ e . SourceByteSize = new FileInfo ( sourcePath ) . Length ;
86+ e . TargetByteSize = new FileInfo ( targetPath ) . Length ;
87+ e . SSHA256 = Utils . GetSHA256OfFile ( sourcePath ) ;
88+ e . TSHA256 = Utils . GetSHA256OfFile ( targetPath ) ;
89+ e . download = "" ;
90+ e . isDirectDownload = true ;
91+ string diffPath = outputPath + e . diffFilename ;
92+ Logger . Log ( "Encoding diff file for " + e . sourceFilename + " -> " + e . outputFilename + " to " +
93+ e . diffFilename ) ;
94+ Process . Start ( "xdelta3.exe" , "-e -s \" " + sourcePath + "\" \" " + targetPath + "\" \" " + diffPath + "\" " ) . WaitForExit ( ) ;
95+
96+ e . DSHA256 = Utils . GetSHA256OfFile ( diffPath ) ;
97+ e . DiffByteSize = new FileInfo ( diffPath ) . Length ;
98+ return e ;
99+ }
100+ }
101+ }
0 commit comments