@@ -15,6 +15,11 @@ namespace IPA
1515
1616 public class Program
1717 {
18+ public enum Architecture {
19+ x86 ,
20+ x64 ,
21+ Unknown
22+ }
1823
1924 static void Main ( string [ ] args )
2025 {
@@ -65,7 +70,12 @@ private static void Install(PatchContext context)
6570 var nativePluginFolder = Path . Combine ( context . DataPathDst , "Plugins" ) ;
6671 bool isFlat = Directory . Exists ( nativePluginFolder ) && Directory . GetFiles ( nativePluginFolder ) . Any ( f => f . EndsWith ( ".dll" ) ) ;
6772 bool force = ! BackupManager . HasBackup ( context ) || context . Args . Contains ( "-f" ) || context . Args . Contains ( "--force" ) ;
68- CopyAll ( new DirectoryInfo ( context . DataPathSrc ) , new DirectoryInfo ( context . DataPathDst ) , force , backup , ( from , to ) => NativePluginInterceptor ( from , to , new DirectoryInfo ( nativePluginFolder ) , isFlat ) ) ;
73+ var architecture = DetectArchitecture ( context . Executable ) ;
74+
75+ Console . WriteLine ( "Architecture: {0}" , architecture ) ;
76+
77+ CopyAll ( new DirectoryInfo ( context . DataPathSrc ) , new DirectoryInfo ( context . DataPathDst ) , force , backup ,
78+ ( from , to ) => NativePluginInterceptor ( from , to , new DirectoryInfo ( nativePluginFolder ) , isFlat , architecture ) ) ;
6979
7080 Console . WriteLine ( "Successfully updated files!" ) ;
7181
@@ -102,25 +112,33 @@ private static void Install(PatchContext context)
102112 if ( ! File . Exists ( context . ShortcutPath ) )
103113 {
104114 Console . Write ( "Creating shortcut to IPA ({0})... " , context . IPA ) ;
105- Shortcut . Create (
106- fileName : context . ShortcutPath ,
107- targetPath : context . IPA ,
108- arguments : Args ( context . Executable , "--launch" ) ,
109- workingDirectory : context . ProjectRoot ,
110- description : "Launches the game and makes sure it's in a patched state" ,
111- hotkey : "" ,
112- iconPath : context . Executable
113- ) ;
114-
115- Console . WriteLine ( "Created" ) ;
115+ try
116+ {
117+ Shortcut . Create (
118+ fileName : context . ShortcutPath ,
119+ targetPath : context . IPA ,
120+ arguments : Args ( context . Executable , "--launch" ) ,
121+ workingDirectory : context . ProjectRoot ,
122+ description : "Launches the game and makes sure it's in a patched state" ,
123+ hotkey : "" ,
124+ iconPath : context . Executable
125+ ) ;
126+ Console . WriteLine ( "Created" ) ;
127+ } catch ( Exception e )
128+ {
129+ Console . Error . WriteLine ( "Failed to create shortcut, but game was patched!" ) ;
130+ }
116131 }
117132 }
118133 catch ( Exception e )
119134 {
120135 Fail ( "Oops! This should not have happened.\n \n " + e ) ;
121136 }
122137
138+
139+ Console . ForegroundColor = ConsoleColor . Green ;
123140 Console . WriteLine ( "Finished!" ) ;
141+ Console . ResetColor ( ) ;
124142
125143 }
126144
@@ -165,7 +183,7 @@ private static void StartIfNeedBe(PatchContext context)
165183 }
166184 }
167185
168- public static IEnumerable < FileInfo > NativePluginInterceptor ( FileInfo from , FileInfo to , DirectoryInfo nativePluginFolder , bool isFlat )
186+ public static IEnumerable < FileInfo > NativePluginInterceptor ( FileInfo from , FileInfo to , DirectoryInfo nativePluginFolder , bool isFlat , Architecture preferredArchitecture )
169187 {
170188 if ( to . FullName . StartsWith ( nativePluginFolder . FullName ) )
171189 {
@@ -175,12 +193,17 @@ public static IEnumerable<FileInfo> NativePluginInterceptor(FileInfo from, FileI
175193 if ( isFlat && ! isFileFlat )
176194 {
177195 // Flatten structure
178- if ( relevantBit . StartsWith ( "x86_64" ) )
196+ bool is64Bit = relevantBit . StartsWith ( "x86_64" ) ;
197+ if ( ! is64Bit && preferredArchitecture == Architecture . x86 )
179198 {
180- yield return new FileInfo ( Path . Combine ( nativePluginFolder . FullName , relevantBit . Substring ( "x86_64" . Length + 1 ) ) ) ;
199+ // 32 bit
200+ yield return new FileInfo ( Path . Combine ( nativePluginFolder . FullName , relevantBit . Substring ( "x86" . Length + 1 ) ) ) ;
181201 }
182- else
202+ else if ( is64Bit && ( preferredArchitecture == Architecture . x64 || preferredArchitecture == Architecture . Unknown ) )
183203 {
204+ // 64 bit
205+ yield return new FileInfo ( Path . Combine ( nativePluginFolder . FullName , relevantBit . Substring ( "x86_64" . Length + 1 ) ) ) ;
206+ } else {
184207 // Throw away
185208 yield break ;
186209 }
@@ -268,6 +291,34 @@ public static string EncodeParameterArgument(string original)
268291 return value ;
269292 }
270293
294+ public static Architecture DetectArchitecture ( string assembly )
295+ {
296+ using ( var reader = new BinaryReader ( File . OpenRead ( assembly ) ) )
297+ {
298+ var header = reader . ReadUInt16 ( ) ;
299+ if ( header == 0x5a4d )
300+ {
301+ reader . BaseStream . Seek ( 60 , SeekOrigin . Begin ) ; // this location contains the offset for the PE header
302+ var peOffset = reader . ReadUInt32 ( ) ;
303+
304+ reader . BaseStream . Seek ( peOffset + 4 , SeekOrigin . Begin ) ;
305+ var machine = reader . ReadUInt16 ( ) ;
306+
307+ if ( machine == 0x8664 ) // IMAGE_FILE_MACHINE_AMD64
308+ return Architecture . x64 ;
309+ else if ( machine == 0x014c ) // IMAGE_FILE_MACHINE_I386
310+ return Architecture . x86 ;
311+ else if ( machine == 0x0200 ) // IMAGE_FILE_MACHINE_IA64
312+ return Architecture . x64 ;
313+ else
314+ return Architecture . Unknown ;
315+ } else
316+ {
317+ // Not a supported binary
318+ return Architecture . Unknown ;
319+ }
320+ }
321+ }
271322
272323 public abstract class Keyboard
273324 {
0 commit comments