Skip to content

Commit dc23b8b

Browse files
committed
Copy correct native DLLs depending on architecture.
1 parent 0df8b1e commit dc23b8b

File tree

1 file changed

+67
-16
lines changed

1 file changed

+67
-16
lines changed

IPA/Program.cs

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)