1
1
using System ;
2
2
using System . Collections . Generic ;
3
+ using System . Diagnostics ;
3
4
using System . IO ;
4
5
using System . Linq ;
5
6
using System . Threading . Tasks ;
@@ -12,36 +13,24 @@ namespace AutoTOC
12
13
{
13
14
class Program
14
15
{
15
- enum MEGame
16
- {
17
- ME3 ,
18
- LE1 ,
19
- LE2 ,
20
- LE3
21
- }
22
-
23
16
static void Main ( string [ ] args )
24
17
{
25
18
string gameDir ;
19
+ MEGame game = MEGame . ME3 ;
26
20
27
21
if ( args . Length == 1 )
28
22
{
29
- // Path is passed in, hopefully is game root directory or .exe
23
+ // Path is passed in, hopefully is game .exe
30
24
gameDir = args [ 0 ] ;
31
- if ( gameDir . EndsWith ( "\" " ) )
25
+ if ( gameDir . EndsWith ( ".exe " ) )
32
26
{
33
- gameDir = gameDir . Remove ( gameDir . Length - 1 ) ;
34
- }
35
- else if ( gameDir . EndsWith ( ".exe" ) )
36
- {
37
- gameDir = GetGamepathFromExe ( gameDir ) ;
27
+ ( gameDir , game ) = GetGamepathFromExe ( gameDir ) ;
38
28
}
39
29
}
40
30
else if ( args . Length == 2 && args [ 0 ] == "-r" )
41
31
{
42
32
try {
43
- MEGame game = ( MEGame ) Enum . Parse ( typeof ( MEGame ) , args [ 1 ] , true ) ;
44
-
33
+ game = ( MEGame ) Enum . Parse ( typeof ( MEGame ) , args [ 1 ] , true ) ;
45
34
gameDir = GetGamepathFromRegistry ( game ) ;
46
35
if ( game != MEGame . ME3 )
47
36
{
@@ -72,18 +61,18 @@ static void Main(string[] args)
72
61
}
73
62
else
74
63
{
75
- Console . WriteLine ( "Requires one argument: the install dir or .exe of the game you're trying to TOC." ) ;
76
- Console . WriteLine ( "(eg. \" D:\\ Origin Games\\ Mass Effect Legendary Edition\\ ME3\" )" ) ;
64
+ Console . WriteLine ( "Requires one argument: .exe of the game you're trying to TOC." ) ;
65
+ Console . WriteLine ( "(eg. \" D:\\ Origin Games\\ Mass Effect Legendary Edition\\ ME3\\ Binaries \\ Win64 \\ MassEffect3.exe )" ) ;
77
66
Console . WriteLine ( "Detect game from registry with -r {game}. Options: ME3, LE1, LE2, LE3" ) ;
78
67
return ;
79
68
}
80
69
81
70
Console . WriteLine ( $ "Generating TOCs for { gameDir } ") ;
82
- GenerateTocFromGamedir ( gameDir ) ;
71
+ GenerateTocFromGamedir ( gameDir , game ) ;
83
72
Console . WriteLine ( "Done!" ) ;
84
73
}
85
74
86
- static void GenerateTocFromGamedir ( string gameDir )
75
+ static void GenerateTocFromGamedir ( string gameDir , MEGame game )
87
76
{
88
77
string baseDir = Path . Combine ( gameDir , @"BIOGame\" ) ;
89
78
string dlcDir = Path . Combine ( baseDir , @"DLC\" ) ;
@@ -97,151 +86,54 @@ static void GenerateTocFromGamedir(string gameDir)
97
86
{
98
87
Console . WriteLine ( "DLC folder not detected, TOCing basegame only..." ) ;
99
88
}
100
- Task . WhenAll ( folders . Select ( loc => TOCAsync ( loc ) ) ) . Wait ( ) ;
89
+ Task . WhenAll ( folders . Select ( loc => TOCAsync ( loc , game ) ) ) . Wait ( ) ;
101
90
}
102
91
103
- static Task TOCAsync ( string tocLoc )
92
+ static Task TOCAsync ( string tocLoc , MEGame game )
104
93
{
105
- return Task . Run ( ( ) => PrepareToCreateTOC ( tocLoc ) ) ;
94
+ return Task . Run ( ( ) => CreateTOC ( tocLoc , game ) ) ;
106
95
}
107
96
108
- static void PrepareToCreateTOC ( string consoletocFile )
97
+ static void CreateTOC ( string tocLoc , MEGame game )
109
98
{
110
- if ( ! consoletocFile . EndsWith ( "\\ " ) ) consoletocFile += "\\ " ;
111
- List < string > files = GetFiles ( consoletocFile ) ;
112
-
113
- if ( files . Count > 0 )
114
- {
115
- string t = files [ 0 ] ;
116
- int n = t . LastIndexOf ( "DLC_" ) ;
117
- if ( n > 0 )
118
- {
119
- for ( int i = 0 ; i < files . Count ; i ++ )
120
- files [ i ] = files [ i ] . Substring ( n ) ;
121
- string t2 = files [ 0 ] ;
122
- n = t2 . IndexOf ( "\\ " ) ;
123
- for ( int i = 0 ; i < files . Count ; i ++ )
124
- files [ i ] = files [ i ] . Substring ( n + 1 ) ;
125
- }
126
- else
127
- {
128
- n = t . LastIndexOf ( "BIOGame" ) ;
129
- if ( n > 0 )
130
- {
131
- for ( int i = 0 ; i < files . Count ; i ++ )
132
- files [ i ] = files [ i ] . Substring ( n ) ;
133
- }
134
- }
135
- string pathbase ;
136
- string t3 = files [ 0 ] ;
137
- int n2 = t3 . LastIndexOf ( "BIOGame" ) ;
138
- if ( n2 >= 0 )
139
- {
140
- pathbase = Path . GetDirectoryName ( Path . GetDirectoryName ( consoletocFile ) ) + "\\ " ;
141
- }
142
- else
143
- {
144
- pathbase = consoletocFile ;
145
- }
146
- CreateTOC ( pathbase , consoletocFile + "PCConsoleTOC.bin" , files . ToArray ( ) ) ;
147
- }
148
- }
149
-
150
- static void CreateTOC ( string basepath , string tocFile , string [ ] files )
151
- {
152
- FileStream fs = new FileStream ( tocFile , FileMode . Create , FileAccess . Write ) ;
153
- long selfSizePosition = - 1 ;
154
- fs . Write ( BitConverter . GetBytes ( ( int ) 0x3AB70C13 ) , 0 , 4 ) ;
155
- fs . Write ( BitConverter . GetBytes ( ( int ) 0x0 ) , 0 , 4 ) ;
156
- fs . Write ( BitConverter . GetBytes ( ( int ) 0x1 ) , 0 , 4 ) ;
157
- fs . Write ( BitConverter . GetBytes ( ( int ) 0x8 ) , 0 , 4 ) ;
158
- fs . Write ( BitConverter . GetBytes ( ( int ) files . Length ) , 0 , 4 ) ;
159
- for ( int i = 0 ; i < files . Length ; i ++ )
160
- {
161
- string file = files [ i ] ;
162
- if ( i == files . Length - 1 ) //Entry Size
163
- fs . Write ( new byte [ 2 ] , 0 , 2 ) ;
164
- else
165
- fs . Write ( BitConverter . GetBytes ( ( ushort ) ( 0x1D + file . Length ) ) , 0 , 2 ) ;
166
- fs . Write ( BitConverter . GetBytes ( ( ushort ) 0 ) , 0 , 2 ) ; //Flags
167
- if ( Path . GetFileName ( file ) . ToLower ( ) != "pcconsoletoc.bin" )
168
- {
169
- fs . Write ( BitConverter . GetBytes ( ( int ) ( new FileInfo ( basepath + file ) . Length ) ) , 0 , 4 ) ; //Filesize
170
- }
171
- else
172
- {
173
- selfSizePosition = fs . Position ;
174
- fs . Write ( BitConverter . GetBytes ( ( int ) 0 ) , 0 , 4 ) ; //Filesize
175
- }
176
- fs . Write ( BitConverter . GetBytes ( ( int ) 0x0 ) , 0 , 4 ) ; //SHA1
177
- fs . Write ( BitConverter . GetBytes ( ( int ) 0x0 ) , 0 , 4 ) ;
178
- fs . Write ( BitConverter . GetBytes ( ( int ) 0x0 ) , 0 , 4 ) ;
179
- fs . Write ( BitConverter . GetBytes ( ( int ) 0x0 ) , 0 , 4 ) ;
180
- fs . Write ( BitConverter . GetBytes ( ( int ) 0x0 ) , 0 , 4 ) ;
181
- foreach ( char c in file )
182
- fs . WriteByte ( ( byte ) c ) ;
183
- fs . WriteByte ( 0 ) ;
184
- }
185
- if ( selfSizePosition >= 0 )
186
- {
187
- // Write the size of our own TOC. This ensures TOC appears up to date when we try to update it later
188
- // (important for DLC TOCs)
189
- fs . Seek ( selfSizePosition , SeekOrigin . Begin ) ;
190
- fs . Write ( BitConverter . GetBytes ( ( int ) fs . Length ) , 0 , 4 ) ;
191
- }
192
- fs . Close ( ) ;
193
- }
194
-
195
- static List < string > GetFiles ( string basefolder )
196
- {
197
- List < string > res = new List < string > ( ) ;
198
- string test = Path . GetFileName ( Path . GetDirectoryName ( basefolder ) ) ;
199
- string [ ] files = GetTocableFiles ( basefolder ) ;
200
- res . AddRange ( files ) ;
201
- DirectoryInfo folder = new DirectoryInfo ( basefolder ) ;
202
- DirectoryInfo [ ] folders = folder . GetDirectories ( ) ;
203
- if ( folders . Length != 0 )
204
- if ( test != "BIOGame" )
205
- foreach ( DirectoryInfo f in folders )
206
- res . AddRange ( GetFiles ( basefolder + f . Name + "\\ " ) ) ;
207
- else
208
- foreach ( DirectoryInfo f in folders )
209
- if ( f . Name == "CookedPCConsole" || f . Name == "Movies" || f . Name == "Splash" )
210
- res . AddRange ( GetFiles ( Path . Combine ( basefolder , f . Name ) ) ) ;
211
- else if ( f . Name == "Content" )
212
- res . AddRange ( GetFiles ( Path . Combine ( basefolder , f . Name , "Packages\\ ISACT" ) ) ) ;
213
-
214
- return res ;
215
- }
216
-
217
- static string [ ] Pattern = { "*.pcc" , "*.afc" , "*.bik" , "*.bin" , "*.tlk" , "*.txt" , "*.cnd" , "*.upk" , "*.tfc" , "*.isb" } ;
218
-
219
- static string [ ] GetTocableFiles ( string path )
220
- {
221
- List < string > res = new List < string > ( ) ;
222
- foreach ( string s in Pattern )
223
- res . AddRange ( Directory . GetFiles ( path , s ) ) ;
224
- return res . ToArray ( ) ;
99
+ var TOC = TOCCreator . CreateTOCForDirectory ( tocLoc , game ) ;
100
+ TOC . WriteToFile ( Path . Combine ( tocLoc , "PCConsoleTOC.bin" ) ) ;
225
101
}
226
102
227
103
static string [ ] ValidExecutables = { "MassEffect1.exe" , "MassEffect2.exe" , "MassEffect3.exe" } ;
228
104
229
- static string GetGamepathFromExe ( string path )
105
+ static ( string , MEGame ) GetGamepathFromExe ( string path )
230
106
{
231
- if ( path != null && ValidExecutables . Any ( ( exe ) => path . EndsWith ( exe ) ) )
107
+ if ( File . Exists ( path ) && ValidExecutables . Any ( ( exe ) => path . EndsWith ( exe ) ) )
232
108
{
233
- return path . Substring ( 0 , path . LastIndexOf ( "Binaries" , StringComparison . OrdinalIgnoreCase ) ) ;
109
+ var dir = path . Substring ( 0 , path . LastIndexOf ( "Binaries" , StringComparison . OrdinalIgnoreCase ) ) ;
110
+ if ( path . EndsWith ( ValidExecutables [ 0 ] ) ) return ( dir , MEGame . LE1 ) ;
111
+ if ( path . EndsWith ( ValidExecutables [ 1 ] ) ) return ( dir , MEGame . LE2 ) ;
112
+ if ( path . EndsWith ( ValidExecutables [ 2 ] ) )
113
+ {
114
+ var versionInfo = FileVersionInfo . GetVersionInfo ( path ) ;
115
+ if ( versionInfo . FileVersion . StartsWith ( "1" ) ) return ( dir , MEGame . ME3 ) ;
116
+ else return ( dir , MEGame . LE3 ) ;
117
+ }
118
+ // Should never get here
119
+ throw new ArgumentException ( "Executable file is not a supported Mass Effect game." ) ;
234
120
}
235
- else throw new ArgumentException ( "Executable file is not a supported Mass Effect game." ) ;
121
+ throw new ArgumentException ( "Executable file is not a supported Mass Effect game." ) ;
236
122
}
237
123
238
124
static string GetGamepathFromRegistry ( MEGame game )
239
125
{
240
126
if ( game != MEGame . ME3 )
241
127
{
242
- // Get LE path from registry
243
- string hkey64 = @"HKEY_LOCAL_MACHINE\SOFTWARE\BioWare\Mass Effect Legendary Edition" ;
244
- return ( string ) Registry . GetValue ( hkey64 , "Install Dir" , null ) ;
128
+ string hkey64 = @"HKEY_LOCAL_MACHINE\SOFTWARE\BioWare\Mass Effectâ„¢ Legendary Edition" ; // Yes all that weird garbage in this name is required... but not for everyone
129
+ string test = ( string ) Registry . GetValue ( hkey64 , "Install Dir" , null ) ;
130
+ if ( test != null )
131
+ {
132
+ return test ;
133
+ }
134
+ hkey64 = @"HKEY_LOCAL_MACHINE\SOFTWARE\BioWare\Mass Effect Legendary Edition" ; //For those without weird garbage
135
+ test = ( string ) Registry . GetValue ( hkey64 , "Install Dir" , null ) ;
136
+ return test ;
245
137
}
246
138
else
247
139
{
0 commit comments