@@ -8,10 +8,14 @@ namespace UnityDataTools.Analyzer;
88
99public class AnalyzerTool
1010{
11- public int Analyze ( string path , string databaseName , string searchPattern , bool skipReferences )
11+ bool m_Verbose = false ;
12+
13+ public int Analyze ( string path , string databaseName , string searchPattern , bool skipReferences , bool verbose )
1214 {
15+ m_Verbose = verbose ;
16+
1317 using SQLiteWriter writer = new ( databaseName , skipReferences ) ;
14-
18+
1519 try
1620 {
1721 writer . Begin ( ) ;
@@ -21,102 +25,166 @@ public int Analyze(string path, string databaseName, string searchPattern, bool
2125 Console . Error . WriteLine ( $ "Error creating database: { e . Message } ") ;
2226 return 1 ;
2327 }
24-
28+
2529 var timer = new Stopwatch ( ) ;
2630 timer . Start ( ) ;
2731
2832 var files = Directory . GetFiles ( path , searchPattern , SearchOption . AllDirectories ) ;
2933 int i = 1 ;
30- int lastLength = 0 ;
3134 foreach ( var file in files )
3235 {
33- // Automatically ignore these annoying OS X style files meta files.
34- if ( Path . GetFileName ( file ) == ".DS_Store" )
36+ if ( ShouldIgnoreFile ( file ) )
37+ {
38+ var relativePath = Path . GetRelativePath ( path , file ) ;
39+
40+ if ( m_Verbose )
41+ {
42+ Console . WriteLine ( ) ;
43+ Console . WriteLine ( $ "Ignoring { relativePath } ") ;
44+ }
45+ ++ i ;
3546 continue ;
47+ }
48+
49+ ProcessFile ( file , path , writer , i , files . Length ) ;
50+ ++ i ;
51+ }
52+
53+ Console . WriteLine ( ) ;
54+ Console . WriteLine ( "Finalizing database..." ) ;
55+
56+ writer . End ( ) ;
57+
58+ timer . Stop ( ) ;
59+ Console . WriteLine ( ) ;
60+ Console . WriteLine ( $ "Total time: { ( timer . Elapsed . TotalMilliseconds / 1000.0 ) : F3} s") ;
61+
62+ return 0 ;
63+ }
64+
65+ bool ShouldIgnoreFile ( string file )
66+ {
67+ // Unfortunately there is no standard extension for AssetBundles, and SerializedFiles often have no extension at all.
68+ // There is also no distinctive signature at the start of a SerializedFile to immediately recognize it
69+ // (Unity Archives do have this).
70+ // So to reduce noise in UnityDataTool output we filter out files that we have a high confidence are NOT SerializedFiles or Unity Archives.
71+
72+ string fileName = Path . GetFileName ( file ) ;
73+ string extension = Path . GetExtension ( file ) ;
74+
75+ if ( ( fileName == ".DS_Store" ) || // Automatically ignore these annoying OS X style files meta files.
76+ ( fileName == "archive_dependencies.bin" ) ||
77+ ( fileName == "scene_info.bin" ) ||
78+ ( fileName == "app.info" ) ||
79+ ( extension == ".txt" ) ||
80+ ( extension == ".resS" ) ||
81+ ( extension == ".resource" ) ||
82+ ( extension == ".json" ) ||
83+ ( extension == ".dll" ) ||
84+ ( extension == ".pdb" ) ||
85+ ( extension == ".manifest" ) ||
86+ ( extension == ".entities" ) ||
87+ ( extension == ".entityheader" ) )
88+ return true ;
89+ return false ;
90+ }
91+
92+ void ProcessFile ( string file , string rootDirectory , SQLiteWriter writer , int fileIndex , int cntFiles )
93+ {
94+ try
95+ {
96+ UnityArchive archive = null ;
3697
3798 try
3899 {
39- UnityArchive archive = null ;
100+ archive = UnityFileSystem . MountArchive ( file , "archive:" + Path . DirectorySeparatorChar ) ;
101+ }
102+ catch ( NotSupportedException )
103+ {
104+ // It wasn't an AssetBundle, try to open the file as a SerializedFile.
105+
106+ var relativePath = Path . GetRelativePath ( rootDirectory , file ) ;
107+ writer . WriteSerializedFile ( relativePath , file , Path . GetDirectoryName ( file ) ) ;
108+
109+ ReportProgress ( relativePath , fileIndex , cntFiles ) ;
110+ }
40111
112+ if ( archive != null )
113+ {
41114 try
42115 {
43- archive = UnityFileSystem . MountArchive ( file , "archive:" + Path . DirectorySeparatorChar ) ;
44- }
45- catch ( NotSupportedException )
46- {
47- // It wasn't an AssetBundle, try to open the file as a SerializedFile.
48-
49- var relativePath = Path . GetRelativePath ( path , file ) ;
116+ var assetBundleName = Path . GetRelativePath ( rootDirectory , file ) ;
50117
51- writer . WriteSerializedFile ( relativePath , file , Path . GetDirectoryName ( file ) ) ;
52-
53- var message = $ "Processing { i * 100 / files . Length } % ({ i } /{ files . Length } ) { file } ";
54- Console . Write ( $ "\r Processing { i * 100 / files . Length } % ({ i } /{ files . Length } ) { file } ") ;
55- lastLength = message . Length ;
56- }
118+ writer . BeginAssetBundle ( assetBundleName , new FileInfo ( file ) . Length ) ;
119+ ReportProgress ( assetBundleName , fileIndex , cntFiles ) ;
57120
58- if ( archive != null )
59- {
60- try
121+ foreach ( var node in archive . Nodes )
61122 {
62- var assetBundleName = Path . GetRelativePath ( path , file ) ;
63-
64- writer . BeginAssetBundle ( assetBundleName , new FileInfo ( file ) . Length ) ;
65-
66- var message = $ "Processing { i * 100 / files . Length } % ({ i } /{ files . Length } ) { assetBundleName } ";
67- Console . Write ( $ "\r { message } { new string ( ' ' , Math . Max ( 0 , lastLength - message . Length ) ) } ") ;
68- lastLength = message . Length ;
69-
70- foreach ( var node in archive . Nodes )
123+ if ( node . Flags . HasFlag ( ArchiveNodeFlags . SerializedFile ) )
71124 {
72- if ( node . Flags . HasFlag ( ArchiveNodeFlags . SerializedFile ) )
125+ try
126+ {
127+ writer . WriteSerializedFile ( node . Path , "archive:/" + node . Path , Path . GetDirectoryName ( file ) ) ;
128+ }
129+ catch ( Exception e )
73130 {
74- try
75- {
76- writer . WriteSerializedFile ( node . Path , "archive:/" + node . Path , Path . GetDirectoryName ( file ) ) ;
77- }
78- catch ( Exception e )
79- {
80- Console . Error . WriteLine ( $ "\r Error processing { node . Path } in archive { file } { new string ( ' ' , Math . Max ( 0 , lastLength - message . Length ) ) } ") ;
81- Console . Error . WriteLine ( e ) ;
82- Console . WriteLine ( ) ;
83- }
131+ EraseProgressLine ( ) ;
132+ Console . Error . WriteLine ( $ "Error processing { node . Path } in archive { file } ") ;
133+ Console . Error . WriteLine ( e ) ;
134+ Console . WriteLine ( ) ;
84135 }
85136 }
86137 }
87- finally
88- {
89- Console . Write ( $ "\r { new string ( ' ' , lastLength ) } ") ;
90- writer . EndAssetBundle ( ) ;
91- archive . Dispose ( ) ;
92- }
138+ }
139+ finally
140+ {
141+ writer . EndAssetBundle ( ) ;
142+ archive . Dispose ( ) ;
93143 }
94144 }
95- catch ( NotSupportedException ) {
96- Console . Error . WriteLine ( ) ;
97- //Console.Error.WriteLine($"File not supported: {file}"); // This is commented out because another codepath will output "failed to load"
98- }
99- catch ( Exception e )
100- {
101- Console . Error . WriteLine ( ) ;
102- Console . Error . WriteLine ( $ "Error processing file: { file } ") ;
103- Console . Write ( $ "{ e . GetType ( ) } : ") ;
104- Console . WriteLine ( e . Message ) ;
145+ EraseProgressLine ( ) ;
146+ }
147+ catch ( NotSupportedException )
148+ {
149+ EraseProgressLine ( ) ;
150+ Console . Error . WriteLine ( ) ;
151+ //Console.Error.WriteLine($"File not supported: {file}"); // This is commented out because another codepath will output "failed to load"
152+ }
153+ catch ( Exception e )
154+ {
155+ EraseProgressLine ( ) ;
156+ Console . Error . WriteLine ( ) ;
157+ Console . Error . WriteLine ( $ "Error processing file: { file } ") ;
158+ Console . WriteLine ( $ "{ e . GetType ( ) } : { e . Message } ") ;
159+ if ( m_Verbose )
105160 Console . WriteLine ( e . StackTrace ) ;
106- }
107-
108- ++ i ;
109161 }
162+ }
110163
111- Console . WriteLine ( ) ;
112- Console . WriteLine ( "Finalizing database..." ) ;
164+ int m_LastProgressMessageLength = 0 ;
113165
114- writer . End ( ) ;
166+ void ReportProgress ( string relativePath , int fileIndex , int cntFiles )
167+ {
168+ var message = $ "Processing { fileIndex * 100 / cntFiles } % ({ fileIndex } /{ cntFiles } ) { relativePath } ";
169+ if ( ! m_Verbose )
170+ {
171+ EraseProgressLine ( ) ;
172+ Console . Write ( $ "\r { message } ") ;
173+ }
174+ else
175+ {
176+ Console . WriteLine ( ) ;
177+ Console . WriteLine ( message ) ;
178+ }
115179
116- timer . Stop ( ) ;
117- Console . WriteLine ( ) ;
118- Console . WriteLine ( $ "Total time: { ( timer . Elapsed . TotalMilliseconds / 1000.0 ) : F3} s") ;
180+ m_LastProgressMessageLength = message . Length ;
181+ }
119182
120- return 0 ;
183+ void EraseProgressLine ( )
184+ {
185+ if ( ! m_Verbose )
186+ Console . Write ( $ "\r { new string ( ' ' , m_LastProgressMessageLength ) } ") ;
187+ else
188+ Console . WriteLine ( ) ;
121189 }
122- }
190+ }
0 commit comments