From 5bd3f0ebcd319ddad54cf59570af81edb105ca7f Mon Sep 17 00:00:00 2001 From: Quit Date: Sat, 8 Dec 2018 13:34:41 +0100 Subject: [PATCH 1/5] Allow --ipa-console to override fullscreen check --- IllusionInjector/Bootstrapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IllusionInjector/Bootstrapper.cs b/IllusionInjector/Bootstrapper.cs index 29f46c5..1561198 100644 --- a/IllusionInjector/Bootstrapper.cs +++ b/IllusionInjector/Bootstrapper.cs @@ -12,7 +12,7 @@ namespace IllusionInjector void Awake() { - if (Environment.CommandLine.Contains("--verbose") && !Screen.fullScreen) + if (Environment.CommandLine.Contains("--verbose") && (!Screen.fullScreen || Environment.CommandLine.Contains("--ipa-console"))) { Windows.GuiConsole.CreateConsole(); } From f8b3d8df51664b115e9225a7bc0b13e917e47d1e Mon Sep 17 00:00:00 2001 From: Quit Date: Sat, 8 Dec 2018 13:38:55 +0100 Subject: [PATCH 2/5] Ignore non-constructable plugins --- IllusionInjector/PluginManager.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/IllusionInjector/PluginManager.cs b/IllusionInjector/PluginManager.cs index 2a7f836..c0af204 100644 --- a/IllusionInjector/PluginManager.cs +++ b/IllusionInjector/PluginManager.cs @@ -48,7 +48,7 @@ namespace IllusionInjector { _Plugins.AddRange(LoadPluginsFromFile(Path.Combine(pluginDirectory, s), exeName)); } - + // DEBUG Console.WriteLine("Running on Unity {0}", UnityEngine.Application.unityVersion); @@ -76,7 +76,7 @@ namespace IllusionInjector foreach (Type t in assembly.GetTypes()) { - if (t.GetInterface("IPlugin") != null) + if (IsValidPlugin(t)) { try { @@ -108,6 +108,14 @@ namespace IllusionInjector return plugins; } + private static bool IsValidPlugin(Type type) + { + return type.GetInterface("IPlugin") != null + && !type.IsAbstract + && !type.IsInterface + && type.GetConstructor(Type.EmptyTypes) != null; + } + public class AppInfo { [DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)] From 7e9528051efc62a086871f77539b0a3c041142f7 Mon Sep 17 00:00:00 2001 From: Quit Date: Sat, 8 Dec 2018 14:35:18 +0100 Subject: [PATCH 3/5] Log the used .NET version on startup. --- IllusionInjector/PluginManager.cs | 32 ++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/IllusionInjector/PluginManager.cs b/IllusionInjector/PluginManager.cs index c0af204..84a3b34 100644 --- a/IllusionInjector/PluginManager.cs +++ b/IllusionInjector/PluginManager.cs @@ -51,7 +51,7 @@ namespace IllusionInjector // DEBUG - Console.WriteLine("Running on Unity {0}", UnityEngine.Application.unityVersion); + Console.WriteLine("Running on Unity {0} using {1}", UnityEngine.Application.unityVersion, GetFrameworkVersion()); Console.WriteLine("-----------------------------"); Console.WriteLine("Loading plugins from {0} and found {1}", pluginDirectory, _Plugins.Count); Console.WriteLine("-----------------------------"); @@ -116,6 +116,36 @@ namespace IllusionInjector && type.GetConstructor(Type.EmptyTypes) != null; } + private static string GetFrameworkVersion() + { + var version = Environment.Version.ToString(); + + try + { + switch (version) + { + case "2.0.50727.1433": + return ".NET 3.5 Equivalent"; + case "4.0.30319.17020": + // For reasons unknown, switching to netstandard seems to set this back to .NET 4.0 + var netstandard = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == "netstandard"); + if (netstandard != null) + return $".NET Standard {netstandard.GetName().Version.ToString(2)}"; + + goto default; + case "4.0.30319.42000": + return ".NET 4.x"; + default: + return $".NET Framework {version}"; + } + } + catch + { + // In case something goes wrong, return the best we can guess + return version; + } + } + public class AppInfo { [DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)] From f6eeb843b9f05bdf75b2c5dde1b293c3b45656e6 Mon Sep 17 00:00:00 2001 From: Quit Date: Sat, 8 Dec 2018 14:38:15 +0100 Subject: [PATCH 4/5] Improve plugin detection to allow inheritance --- IllusionInjector/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IllusionInjector/PluginManager.cs b/IllusionInjector/PluginManager.cs index 84a3b34..51f93e3 100644 --- a/IllusionInjector/PluginManager.cs +++ b/IllusionInjector/PluginManager.cs @@ -110,7 +110,7 @@ namespace IllusionInjector private static bool IsValidPlugin(Type type) { - return type.GetInterface("IPlugin") != null + return typeof(IPlugin).IsAssignableFrom(type) && !type.IsAbstract && !type.IsInterface && type.GetConstructor(Type.EmptyTypes) != null; From 5683e3c502b1e12252adf1223b38cd47531e39bd Mon Sep 17 00:00:00 2001 From: Quit Date: Mon, 21 Jan 2019 04:49:11 +0100 Subject: [PATCH 5/5] Auto-formatted code --- IPA.Tests/ProgramTest.cs | 8 +- IPA.Tests/ShortcutTest.cs | 4 - IPA/PatchContext.cs | 11 +-- IPA/Patcher/BackupManager.cs | 10 +-- IPA/Patcher/BackupUnit.cs | 28 ++++--- IPA/Patcher/Patcher.cs | 25 +++--- IPA/Patcher/Virtualizer.cs | 27 +++--- IPA/Program.cs | 60 +++++++------ IPA/Shortcut.cs | 4 +- IllusionInjector/Bootstrapper.cs | 16 ++-- IllusionInjector/CompositePlugin.cs | 12 ++- IllusionInjector/ConsoleWindow.cs | 126 ++++++++++++++-------------- IllusionInjector/Injector.cs | 4 +- IllusionInjector/PluginComponent.cs | 23 +++-- IllusionInjector/PluginManager.cs | 22 +++-- IllusionPlugin/IEnhancedPlugin.cs | 6 +- IllusionPlugin/IPlugin.cs | 6 +- IllusionPlugin/IniFile.cs | 4 +- IllusionPlugin/ModPrefs.cs | 7 +- Launcher/Program.cs | 32 +++---- 20 files changed, 206 insertions(+), 229 deletions(-) diff --git a/IPA.Tests/ProgramTest.cs b/IPA.Tests/ProgramTest.cs index 15716a2..ddc15a8 100644 --- a/IPA.Tests/ProgramTest.cs +++ b/IPA.Tests/ProgramTest.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.IO; +using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; using Xunit; namespace IPA.Tests @@ -26,7 +22,7 @@ namespace IPA.Tests // Not-flat -> Not-Flat [InlineData("native/x86/from.dll", "native/x86/to.dll", "native", false, new string[] { "native/x86/to.dll" })] - [InlineData("native/x86_64/from.dll", "native/x86_64/to.dll", "native", false, new string[] { "native/x86_64/to.dll" })] + [InlineData("native/x86_64/from.dll", "native/x86_64/to.dll", "native", false, new string[] { "native/x86_64/to.dll" })] public void CopiesCorrectly(string from, string to, string nativeFolder, bool isFlat, string[] expected) { diff --git a/IPA.Tests/ShortcutTest.cs b/IPA.Tests/ShortcutTest.cs index 3229153..914ef36 100644 --- a/IPA.Tests/ShortcutTest.cs +++ b/IPA.Tests/ShortcutTest.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Xunit; namespace IPA.Tests diff --git a/IPA/PatchContext.cs b/IPA/PatchContext.cs index fc9dac9..b8a64f9 100644 --- a/IPA/PatchContext.cs +++ b/IPA/PatchContext.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Reflection; -using System.Text; namespace IPA { @@ -37,7 +34,7 @@ namespace IPA public static PatchContext Create(String[] args) { var context = new PatchContext(); - + context.Args = args; context.Executable = args[0]; context.ProjectRoot = new FileInfo(context.Executable).Directory.FullName; @@ -49,7 +46,7 @@ namespace IPA context.ProjectName = Path.GetFileNameWithoutExtension(context.Executable); context.DataPathDst = Path.Combine(context.ProjectRoot, context.ProjectName + "_Data"); context.ManagedPath = Path.Combine(context.DataPathDst, "Managed"); - context.EngineFile = DetermineEngineFile(context.ManagedPath, "UnityEngine.CoreModule.dll", "UnityEngine.dll"); + context.EngineFile = DetermineEngineFile(context.ManagedPath, "UnityEngine.CoreModule.dll", "UnityEngine.dll"); context.AssemblyFile = Path.Combine(context.ManagedPath, "Assembly-Csharp.dll"); context.BackupPath = Path.Combine(Path.Combine(context.IPARoot, "Backups"), context.ProjectName); context.ShortcutPath = Path.Combine(context.ProjectRoot, $"{context.ProjectName} (Patch & Launch)") + ".lnk"; @@ -61,10 +58,10 @@ namespace IPA private static string DetermineEngineFile(string basePath, params string[] candidates) { - foreach(var candidate in candidates) + foreach (var candidate in candidates) { var fullPath = Path.Combine(basePath, candidate); - if(File.Exists(fullPath)) + if (File.Exists(fullPath)) { return fullPath; } diff --git a/IPA/Patcher/BackupManager.cs b/IPA/Patcher/BackupManager.cs index 511a22d..6795344 100644 --- a/IPA/Patcher/BackupManager.cs +++ b/IPA/Patcher/BackupManager.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.IO; +using System.IO; using System.Linq; -using System.Text; -using System.Text.RegularExpressions; namespace IPA.Patcher { @@ -22,11 +18,11 @@ namespace IPA.Patcher { return FindLatestBackup(context) != null; } - + public static bool Restore(PatchContext context) { var backup = FindLatestBackup(context); - if(backup != null) + if (backup != null) { backup.Restore(); backup.Delete(); diff --git a/IPA/Patcher/BackupUnit.cs b/IPA/Patcher/BackupUnit.cs index 3949072..1c6489a 100644 --- a/IPA/Patcher/BackupUnit.cs +++ b/IPA/Patcher/BackupUnit.cs @@ -1,9 +1,6 @@ using System; using System.Collections.Generic; -using System.Collections.Specialized; using System.IO; -using System.Linq; -using System.Text; namespace IPA.Patcher { @@ -30,13 +27,14 @@ namespace IPA.Patcher _Context = context; _BackupPath = new DirectoryInfo(Path.Combine(_Context.BackupPath, Name)); } - + public static BackupUnit FromDirectory(DirectoryInfo directory, PatchContext context) { var unit = new BackupUnit(context, directory.Name); // Parse directory - foreach(var file in directory.GetFiles("*", SearchOption.AllDirectories)) { + foreach (var file in directory.GetFiles("*", SearchOption.AllDirectories)) + { var relativePath = file.FullName.Substring(directory.FullName.Length + 1); unit._Files.Add(relativePath); } @@ -60,7 +58,7 @@ namespace IPA.Patcher /// public void Add(FileInfo file) { - if(!file.FullName.StartsWith(_Context.ProjectRoot)) + if (!file.FullName.StartsWith(_Context.ProjectRoot)) { Console.Error.WriteLine("Invalid file path for backup! {0}", file); return; @@ -68,8 +66,8 @@ namespace IPA.Patcher var relativePath = file.FullName.Substring(_Context.ProjectRoot.Length + 1); var backupPath = new FileInfo(Path.Combine(_BackupPath.FullName, relativePath)); - - if(_Files.Contains(relativePath)) + + if (_Files.Contains(relativePath)) { Console.WriteLine("Skipping backup of {0}", relativePath); return; @@ -81,7 +79,8 @@ namespace IPA.Patcher if (file.Exists) { file.CopyTo(backupPath.FullName); - } else + } + else { // Make empty file backupPath.Create().Close(); @@ -96,7 +95,7 @@ namespace IPA.Patcher /// public void Restore() { - foreach(var relativePath in _Files) + foreach (var relativePath in _Files) { Console.WriteLine("Restoring {0}", relativePath); // Original version @@ -110,15 +109,18 @@ namespace IPA.Patcher Console.WriteLine(" {0} => {1}", backupFile.FullName, target.FullName); target.Directory.Create(); backupFile.CopyTo(target.FullName, true); - } else + } + else { Console.WriteLine(" x {0}", target.FullName); - if(target.Exists) + if (target.Exists) { target.Delete(); } } - } else { + } + else + { Console.Error.WriteLine("Backup not found!"); } } diff --git a/IPA/Patcher/Patcher.cs b/IPA/Patcher/Patcher.cs index 8b0cb14..720e0d5 100644 --- a/IPA/Patcher/Patcher.cs +++ b/IPA/Patcher/Patcher.cs @@ -1,14 +1,13 @@ -using Mono.Cecil; -using Mono.Cecil.Cil; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; +using Mono.Cecil; +using Mono.Cecil.Cil; namespace IPA.Patcher { - class PatchedModule + internal class PatchedModule { private static readonly string[] ENTRY_TYPES = { "Input", "Display" }; @@ -36,7 +35,7 @@ namespace IPA.Patcher { AssemblyResolver = resolver, }; - + _Module = ModuleDefinition.ReadModule(_File.FullName, parameters); } @@ -46,7 +45,8 @@ namespace IPA.Patcher { foreach (var @ref in _Module.AssemblyReferences) { - if (@ref.Name == "IllusionInjector") return true; + if (@ref.Name == "IllusionInjector") + return true; } return false; } @@ -61,18 +61,19 @@ namespace IPA.Patcher _Module.AssemblyReferences.Add(nameReference); int patched = 0; - foreach(var type in FindEntryTypes()) + foreach (var type in FindEntryTypes()) { - if(PatchType(type, injector)) + if (PatchType(type, injector)) { patched++; } } - - if(patched > 0) + + if (patched > 0) { _Module.Write(_File.FullName); - } else + } + else { throw new Exception("Could not find any entry type!"); } diff --git a/IPA/Patcher/Virtualizer.cs b/IPA/Patcher/Virtualizer.cs index ac131cb..b38b45c 100644 --- a/IPA/Patcher/Virtualizer.cs +++ b/IPA/Patcher/Virtualizer.cs @@ -1,13 +1,11 @@ -using Mono.Cecil; -using System; -using System.Collections.Generic; +using System; using System.IO; using System.Linq; -using System.Text; +using Mono.Cecil; namespace IPA.Patcher { - class VirtualizedModule + internal class VirtualizedModule { private const string ENTRY_TYPE = "Display"; @@ -38,7 +36,7 @@ namespace IPA.Patcher _Module = ModuleDefinition.ReadModule(_File.FullName, parameters); } - + /// /// /// @@ -55,17 +53,20 @@ namespace IPA.Patcher private void VirtualizeType(TypeDefinition type) { - if(type.IsSealed) + if (type.IsSealed) { // Unseal type.IsSealed = false; } - if (type.IsInterface) return; - if (type.IsAbstract) return; + if (type.IsInterface) + return; + if (type.IsAbstract) + return; // These two don't seem to work. - if (type.Name == "SceneControl" || type.Name == "ConfigUI") return; + if (type.Name == "SceneControl" || type.Name == "ConfigUI") + return; Console.WriteLine("Virtualizing {0}", type.Name); // Take care of sub types @@ -97,7 +98,8 @@ namespace IPA.Patcher foreach (var field in type.Fields) { - if (field.IsPrivate) field.IsFamily = true; + if (field.IsPrivate) + field.IsFamily = true; } } @@ -106,7 +108,8 @@ namespace IPA.Patcher get { var awakeMethods = _Module.GetTypes().SelectMany(t => t.Methods.Where(m => m.Name == "Awake")); - if (awakeMethods.Count() == 0) return false; + if (awakeMethods.Count() == 0) + return false; return ((float)awakeMethods.Count(m => m.IsVirtual) / awakeMethods.Count()) > 0.5f; } diff --git a/IPA/Program.cs b/IPA/Program.cs index 2752be3..03c196a 100644 --- a/IPA/Program.cs +++ b/IPA/Program.cs @@ -1,29 +1,28 @@ -using IPA.Patcher; -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; -using System.Reflection; using System.Runtime.InteropServices; -using System.Text; using System.Text.RegularExpressions; using System.Windows.Forms; +using IPA.Patcher; namespace IPA { - + public class Program { - public enum Architecture { + public enum Architecture + { x86, x64, Unknown } - static void Main(string[] args) + private static void Main(string[] args) { - if(args.Length < 1 || !args[0].EndsWith(".exe")) + if (args.Length < 1 || !args[0].EndsWith(".exe")) { Fail("Drag an (executable) file on the exe!"); } @@ -44,7 +43,8 @@ namespace IPA Install(context); StartIfNeedBe(context); } - } catch(Exception e) + } + catch (Exception e) { Fail(e.Message); } @@ -52,7 +52,8 @@ namespace IPA private static void Validate(PatchContext c) { - if (!File.Exists(c.LauncherPathSrc)) Fail("Couldn't find DLLs! Make sure you extracted all contents of the release archive."); + if (!File.Exists(c.LauncherPathSrc)) + Fail("Couldn't find DLLs! Make sure you extracted all contents of the release archive."); if (!Directory.Exists(c.DataPathDst) || !File.Exists(c.EngineFile)) { Fail("Game does not seem to be a Unity project. Could not find the libraries to patch."); @@ -74,8 +75,8 @@ namespace IPA Console.WriteLine("Architecture: {0}", architecture); - CopyAll(new DirectoryInfo(context.DataPathSrc), new DirectoryInfo(context.DataPathDst), force, backup, - (from, to) => NativePluginInterceptor(from, to, new DirectoryInfo(nativePluginFolder), isFlat, architecture) ); + CopyAll(new DirectoryInfo(context.DataPathSrc), new DirectoryInfo(context.DataPathDst), force, backup, + (from, to) => NativePluginInterceptor(from, to, new DirectoryInfo(nativePluginFolder), isFlat, architecture)); Console.WriteLine("Successfully updated files!"); @@ -109,9 +110,9 @@ namespace IPA } // Creating shortcut - if(!File.Exists(context.ShortcutPath)) + if (!File.Exists(context.ShortcutPath)) { - Console.Write("Creating shortcut to IPA ({0})... ", context.IPA); + Console.Write("Creating shortcut to IPA ({0})... ", context.IPA); try { Shortcut.Create( @@ -124,7 +125,8 @@ namespace IPA iconPath: context.Executable ); Console.WriteLine("Created"); - } catch (Exception e) + } + catch (Exception e) { Console.Error.WriteLine("Failed to create shortcut, but game was patched!"); } @@ -145,15 +147,16 @@ namespace IPA private static void Revert(PatchContext context) { Console.Write("Restoring backup... "); - if(BackupManager.Restore(context)) + if (BackupManager.Restore(context)) { Console.WriteLine("Done!"); - } else + } + else { Console.WriteLine("Already vanilla!"); } - + if (File.Exists(context.ShortcutPath)) { Console.WriteLine("Deleting shortcut..."); @@ -177,7 +180,7 @@ namespace IPA argList.RemoveAt(0); - if(launch) + if (launch) { Process.Start(context.Executable, Args(argList.ToArray())); } @@ -199,11 +202,13 @@ namespace IPA // 32 bit yield return new FileInfo(Path.Combine(nativePluginFolder.FullName, relevantBit.Substring("x86".Length + 1))); } - else if(is64Bit && (preferredArchitecture == Architecture.x64 || preferredArchitecture == Architecture.Unknown)) + else if (is64Bit && (preferredArchitecture == Architecture.x64 || preferredArchitecture == Architecture.Unknown)) { // 64 bit yield return new FileInfo(Path.Combine(nativePluginFolder.FullName, relevantBit.Substring("x86_64".Length + 1))); - } else { + } + else + { // Throw away yield break; } @@ -231,7 +236,7 @@ namespace IPA public static void CopyAll(DirectoryInfo source, DirectoryInfo target, bool aggressive, BackupUnit backup, Func> interceptor = null) { - if(interceptor == null) + if (interceptor == null) { interceptor = PassThroughInterceptor; } @@ -239,7 +244,8 @@ namespace IPA // Copy each file into the new directory. foreach (FileInfo fi in source.GetFiles()) { - foreach(var targetFile in interceptor(fi, new FileInfo(Path.Combine(target.FullName, fi.Name)))) { + foreach (var targetFile in interceptor(fi, new FileInfo(Path.Combine(target.FullName, fi.Name)))) + { if (!targetFile.Exists || targetFile.LastWriteTimeUtc < fi.LastWriteTimeUtc || aggressive) { targetFile.Directory.Create(); @@ -259,8 +265,7 @@ namespace IPA } } - - static void Fail(string message) + private static void Fail(string message) { Console.Error.Write("ERROR: " + message); if (!Environment.CommandLine.Contains("--nowait")) @@ -296,7 +301,7 @@ namespace IPA using (var reader = new BinaryReader(File.OpenRead(assembly))) { var header = reader.ReadUInt16(); - if(header == 0x5a4d) + if (header == 0x5a4d) { reader.BaseStream.Seek(60, SeekOrigin.Begin); // this location contains the offset for the PE header var peOffset = reader.ReadUInt32(); @@ -312,7 +317,8 @@ namespace IPA return Architecture.x64; else return Architecture.Unknown; - } else + } + else { // Not a supported binary return Architecture.Unknown; diff --git a/IPA/Shortcut.cs b/IPA/Shortcut.cs index 367da55..a671bbf 100644 --- a/IPA/Shortcut.cs +++ b/IPA/Shortcut.cs @@ -3,10 +3,10 @@ using System.Runtime.InteropServices; namespace IPA { - public class Shortcut + public static class Shortcut { private static Type m_type = Type.GetTypeFromProgID("WScript.Shell"); - private static object m_shell = Activator.CreateInstance(m_type); + private static readonly object m_shell = Activator.CreateInstance(m_type); [ComImport, TypeLibType((short)0x1040), Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")] private interface IWshShortcut diff --git a/IllusionInjector/Bootstrapper.cs b/IllusionInjector/Bootstrapper.cs index 1561198..8d93fd5 100644 --- a/IllusionInjector/Bootstrapper.cs +++ b/IllusionInjector/Bootstrapper.cs @@ -1,16 +1,13 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using UnityEngine; namespace IllusionInjector { - class Bootstrapper : MonoBehaviour + internal class Bootstrapper : MonoBehaviour { - public event Action Destroyed = delegate {}; - - void Awake() + public event Action Destroyed = delegate { }; + + private void Awake() { if (Environment.CommandLine.Contains("--verbose") && (!Screen.fullScreen || Environment.CommandLine.Contains("--ipa-console"))) { @@ -18,11 +15,12 @@ namespace IllusionInjector } } - void Start() + private void Start() { Destroy(gameObject); } - void OnDestroy() + + private void OnDestroy() { Destroyed(); } diff --git a/IllusionInjector/CompositePlugin.cs b/IllusionInjector/CompositePlugin.cs index 3a4b0ea..3bcf49f 100644 --- a/IllusionInjector/CompositePlugin.cs +++ b/IllusionInjector/CompositePlugin.cs @@ -1,20 +1,18 @@ -using IllusionPlugin; -using System; +using System; using System.Collections.Generic; -using System.Text; -using UnityEngine; +using IllusionPlugin; namespace IllusionInjector { public class CompositePlugin : IPlugin { - IEnumerable plugins; + private readonly IEnumerable plugins; private delegate void CompositeCall(IPlugin plugin); public CompositePlugin(IEnumerable plugins) { - this.plugins = plugins; + this.plugins = plugins; } public void OnApplicationStart() @@ -24,7 +22,7 @@ namespace IllusionInjector public void OnApplicationQuit() { - Invoke(plugin => plugin.OnApplicationQuit()); + Invoke(plugin => plugin.OnApplicationQuit()); } public void OnLevelWasLoaded(int level) diff --git a/IllusionInjector/ConsoleWindow.cs b/IllusionInjector/ConsoleWindow.cs index 928795e..4cd9c3f 100644 --- a/IllusionInjector/ConsoleWindow.cs +++ b/IllusionInjector/ConsoleWindow.cs @@ -1,71 +1,69 @@ using System; -using System.Collections; -using System.Runtime.InteropServices; using System.IO; +using System.Runtime.InteropServices; using System.Text; namespace Windows { - - class GuiConsole - { - public static void CreateConsole() - { - if (hasConsole) - return; - if (oldOut == IntPtr.Zero) - oldOut = GetStdHandle( -11 ); - if (! AllocConsole()) - throw new Exception("AllocConsole() failed"); - conOut = CreateFile( "CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero ); - if (! SetStdHandle(-11, conOut)) - throw new Exception("SetStdHandle() failed"); - StreamToConsole(); - hasConsole = true; - } - public static void ReleaseConsole() - { - if (! hasConsole) - return; - if (! CloseHandle(conOut)) - throw new Exception("CloseHandle() failed"); - conOut = IntPtr.Zero; - if (! FreeConsole()) - throw new Exception("FreeConsole() failed"); - if (! SetStdHandle(-11, oldOut)) - throw new Exception("SetStdHandle() failed"); - StreamToConsole(); - hasConsole = false; - } - private static void StreamToConsole() - { - Stream cstm = Console.OpenStandardOutput(); - StreamWriter cstw = new StreamWriter( cstm, Encoding.Default ); - cstw.AutoFlush = true; - Console.SetOut( cstw ); - Console.SetError( cstw ); - } - private static bool hasConsole = false; - private static IntPtr conOut; - private static IntPtr oldOut; - [DllImport("kernel32.dll", SetLastError=true)] - private static extern bool AllocConsole(); - [DllImport("kernel32.dll", SetLastError=false)] - private static extern bool FreeConsole(); - [DllImport("kernel32.dll", SetLastError=true)] - private static extern IntPtr GetStdHandle( int nStdHandle ); - [DllImport("kernel32.dll", SetLastError=true)] - private static extern bool SetStdHandle(int nStdHandle, IntPtr hConsoleOutput); - [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] - private static extern IntPtr CreateFile( - string fileName, - int desiredAccess, - int shareMode, - IntPtr securityAttributes, - int creationDisposition, - int flagsAndAttributes, - IntPtr templateFile ); - [DllImport("kernel32.dll", ExactSpelling=true, SetLastError=true)] - private static extern bool CloseHandle(IntPtr handle); - } + internal class GuiConsole + { + public static void CreateConsole() + { + if (hasConsole) + return; + if (oldOut == IntPtr.Zero) + oldOut = GetStdHandle(-11); + if (!AllocConsole()) + throw new Exception("AllocConsole() failed"); + conOut = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero); + if (!SetStdHandle(-11, conOut)) + throw new Exception("SetStdHandle() failed"); + StreamToConsole(); + hasConsole = true; + } + public static void ReleaseConsole() + { + if (!hasConsole) + return; + if (!CloseHandle(conOut)) + throw new Exception("CloseHandle() failed"); + conOut = IntPtr.Zero; + if (!FreeConsole()) + throw new Exception("FreeConsole() failed"); + if (!SetStdHandle(-11, oldOut)) + throw new Exception("SetStdHandle() failed"); + StreamToConsole(); + hasConsole = false; + } + private static void StreamToConsole() + { + Stream cstm = Console.OpenStandardOutput(); + StreamWriter cstw = new StreamWriter(cstm, Encoding.Default); + cstw.AutoFlush = true; + Console.SetOut(cstw); + Console.SetError(cstw); + } + private static bool hasConsole = false; + private static IntPtr conOut; + private static IntPtr oldOut; + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool AllocConsole(); + [DllImport("kernel32.dll", SetLastError = false)] + private static extern bool FreeConsole(); + [DllImport("kernel32.dll", SetLastError = true)] + private static extern IntPtr GetStdHandle(int nStdHandle); + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool SetStdHandle(int nStdHandle, IntPtr hConsoleOutput); + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr CreateFile( + string fileName, + int desiredAccess, + int shareMode, + IntPtr securityAttributes, + int creationDisposition, + int flagsAndAttributes, + IntPtr templateFile); + [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)] + private static extern bool CloseHandle(IntPtr handle); + } } \ No newline at end of file diff --git a/IllusionInjector/Injector.cs b/IllusionInjector/Injector.cs index 592b384..4d10aa7 100644 --- a/IllusionInjector/Injector.cs +++ b/IllusionInjector/Injector.cs @@ -1,6 +1,4 @@ -using System; -using System.IO; -using UnityEngine; +using UnityEngine; namespace IllusionInjector { diff --git a/IllusionInjector/PluginComponent.cs b/IllusionInjector/PluginComponent.cs index d3dc578..269bef4 100644 --- a/IllusionInjector/PluginComponent.cs +++ b/IllusionInjector/PluginComponent.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using UnityEngine; +using UnityEngine; namespace IllusionInjector { @@ -16,7 +13,7 @@ namespace IllusionInjector return new GameObject("IPA_PluginManager").AddComponent(); } - void Awake() + private void Awake() { DontDestroyOnLoad(gameObject); @@ -24,12 +21,12 @@ namespace IllusionInjector plugins.OnApplicationStart(); } - void Start() + private void Start() { OnLevelWasLoaded(Application.loadedLevel); } - void Update() + private void Update() { if (freshlyLoaded) { @@ -39,32 +36,32 @@ namespace IllusionInjector plugins.OnUpdate(); } - void LateUpdate() + private void LateUpdate() { plugins.OnLateUpdate(); } - void FixedUpdate() + private void FixedUpdate() { plugins.OnFixedUpdate(); } - void OnDestroy() + private void OnDestroy() { if (!quitting) { Create(); } } - - void OnApplicationQuit() + + private void OnApplicationQuit() { plugins.OnApplicationQuit(); quitting = true; } - void OnLevelWasLoaded(int level) + private void OnLevelWasLoaded(int level) { plugins.OnLevelWasLoaded(level); freshlyLoaded = true; diff --git a/IllusionInjector/PluginManager.cs b/IllusionInjector/PluginManager.cs index 51f93e3..23dab18 100644 --- a/IllusionInjector/PluginManager.cs +++ b/IllusionInjector/PluginManager.cs @@ -1,13 +1,11 @@ -using IllusionPlugin; -using System; +using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; +using IllusionPlugin; namespace IllusionInjector { @@ -22,7 +20,7 @@ namespace IllusionInjector { get { - if(_Plugins == null) + if (_Plugins == null) { LoadPlugins(); } @@ -41,8 +39,9 @@ namespace IllusionInjector Console.WriteLine(exeName); _Plugins = new List(); - if (!Directory.Exists(pluginDirectory)) return; - + if (!Directory.Exists(pluginDirectory)) + return; + String[] files = Directory.GetFiles(pluginDirectory, "*.dll"); foreach (var s in files) { @@ -80,7 +79,6 @@ namespace IllusionInjector { try { - IPlugin pluginInstance = Activator.CreateInstance(t) as IPlugin; string[] filter = null; @@ -88,8 +86,8 @@ namespace IllusionInjector { filter = ((IEnhancedPlugin)pluginInstance).Filter; } - - if(filter == null || Enumerable.Contains(filter, exeName, StringComparer.OrdinalIgnoreCase)) + + if (filter == null || Enumerable.Contains(filter, exeName, StringComparer.OrdinalIgnoreCase)) plugins.Add(pluginInstance); } catch (Exception e) @@ -111,8 +109,8 @@ namespace IllusionInjector private static bool IsValidPlugin(Type type) { return typeof(IPlugin).IsAssignableFrom(type) - && !type.IsAbstract - && !type.IsInterface + && !type.IsAbstract + && !type.IsInterface && type.GetConstructor(Type.EmptyTypes) != null; } diff --git a/IllusionPlugin/IEnhancedPlugin.cs b/IllusionPlugin/IEnhancedPlugin.cs index 304b4ba..ddd99a0 100644 --- a/IllusionPlugin/IEnhancedPlugin.cs +++ b/IllusionPlugin/IEnhancedPlugin.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace IllusionPlugin +namespace IllusionPlugin { public interface IEnhancedPlugin : IPlugin { diff --git a/IllusionPlugin/IPlugin.cs b/IllusionPlugin/IPlugin.cs index 1c4effd..01af6bc 100644 --- a/IllusionPlugin/IPlugin.cs +++ b/IllusionPlugin/IPlugin.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace IllusionPlugin +namespace IllusionPlugin { /// /// Interface for generic Illusion unity plugins. Every class that implements this will be loaded if the DLL is placed at diff --git a/IllusionPlugin/IniFile.cs b/IllusionPlugin/IniFile.cs index 14e9b81..24a650c 100644 --- a/IllusionPlugin/IniFile.cs +++ b/IllusionPlugin/IniFile.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.IO; +using System.IO; using System.Runtime.InteropServices; using System.Text; diff --git a/IllusionPlugin/ModPrefs.cs b/IllusionPlugin/ModPrefs.cs index acdbd7c..6600edc 100644 --- a/IllusionPlugin/ModPrefs.cs +++ b/IllusionPlugin/ModPrefs.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Text; namespace IllusionPlugin { @@ -58,7 +56,7 @@ namespace IllusionPlugin return value; else if (autoSave) SetInt(section, name, defaultValue); - + return defaultValue; } @@ -96,7 +94,8 @@ namespace IllusionPlugin if (sVal == "1" || sVal == "0") { return sVal == "1"; - } else if (autoSave) + } + else if (autoSave) { SetBool(section, name, defaultValue); } diff --git a/Launcher/Program.cs b/Launcher/Program.cs index 8dd5fca..9ccf720 100644 --- a/Launcher/Program.cs +++ b/Launcher/Program.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; @@ -8,41 +7,43 @@ using System.Windows.Forms; namespace Launcher { - static class Program + internal static class Program { - private static string[] TABOO_NAMES = { + private static readonly string[] TABOO_NAMES = { //"Start", //"Update", //"Awake", //"OnDestroy" }; - private static string[] ENTRY_TYPES = { "Display" }; - + private static readonly string[] ENTRY_TYPES = { "Display" }; + /// /// The main entry point for the application. /// [STAThread] - static void Main() + private static void Main() { - try { + try + { var execPath = Application.ExecutablePath; var fileName = Path.GetFileNameWithoutExtension(execPath); if (fileName.IndexOf("VR") == -1 && fileName.IndexOf("_") == -1) { Fail("File not named correctly!"); } - + bool vrMode = fileName.IndexOf("VR") > 0; string baseName = execPath.Substring(0, vrMode ? execPath.LastIndexOf("VR") : execPath.LastIndexOf("_")); - + string executable = baseName + ".exe"; var file = new FileInfo(executable); if (file.Exists) { var args = Environment.GetCommandLineArgs().ToList(); - if (vrMode) args.Add("--vr"); + if (vrMode) + args.Add("--vr"); EnsureIPA(executable); StartGame(executable, args.ToArray()); } @@ -50,10 +51,12 @@ namespace Launcher { MessageBox.Show("Could not find: " + file.FullName, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } - } catch(Exception globalException) { + } + catch (Exception globalException) + { MessageBox.Show(globalException.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } - + } private static void EnsureIPA(string executable) @@ -65,7 +68,7 @@ namespace Launcher var process = Process.Start(processStart); process.WaitForExit(); - if(process.ExitCode != 0) + if (process.ExitCode != 0) { Fail(process.StandardError.ReadToEnd()); } @@ -77,7 +80,8 @@ namespace Launcher Process.Start(executable, arguments); } - private static void Fail(string reason) { + private static void Fail(string reason) + { throw new Exception(reason); }