public static void GetAllAssembliesInsideDirectory(string directory) { try { foreach (var file in Directory.GetFiles(directory, "*.dll")) { ConsoleHelper.WriteMessage(ConsoleHelper.MessageType.Wait, $"Loading in assembly {Path.GetFileName(file)}.."); var timer = new OperationTimer(); try { var assembly = AssemblyDefinition.ReadAssembly(Path.GetFullPath(file)); var allAttributes = AttributesHelper.GetAllAttributesInAssembly(assembly); var filteredAttributes = AttributesHelper.FindAndInvokeAllAttributes(allAttributes, timer); foreach (var keyValuePair in filteredAttributes) { Program.Attributes.Add(keyValuePair.Key, keyValuePair.Value); } timer.Stop(); ConsoleHelper.WriteMessage(ConsoleHelper.MessageType.Success, $"Loaded in assembly and {filteredAttributes.Sum(x=>x.Value.Count)} attribute(s) in {timer.GetElapsedMs}ms\r\n"); } catch (Exception ex) { ConsoleHelper.WriteError(ex.InnerException.StackTrace); timer.Stop(); ConsoleHelper.WriteError($"Could not load in assembly after {timer.GetElapsedMs}ms."); ConsoleHelper.WriteError($"Message: {ex.Message}"); ConsoleHelper.WriteError(ex.StackTrace); } } } catch (Exception ex) { ConsoleHelper.WriteError($"{ex.Message}\r\nStackTrace:{ex.StackTrace}"); } }
public void FetchAndLoadAll() { try { foreach (var file in Directory.GetFiles(AssemblyDirectory, "*.dll")) { Program.Chalker.WriteWait($"Loading in assembly {Path.GetFileName(file)}.."); var timer = new OperationTimer(); try { var assembly = AssemblyDefinition.ReadAssembly(Path.GetFullPath(file)); var allAttributes = Program.AttributesHelper.FindInAssembly(assembly); var filteredAttributes = Program.AttributesHelper.InstantiateAndInvoke(allAttributes, timer); foreach (var keyValuePair in filteredAttributes) { Program.Attributes.Add(keyValuePair.Key, keyValuePair.Value); } timer.Stop(); Program.Chalker.WriteSuccess($"Loaded in assembly and {filteredAttributes.Sum(x=>x.Value.Count)} attribute(s) in {timer.GetElapsedMs}ms\r\n"); } catch (Exception ex) { Program.Chalker.WriteError(ex.InnerException.StackTrace); timer.Stop(); Program.Chalker.WriteError($"Could not load in assembly after {timer.GetElapsedMs}ms."); Program.Chalker.WriteError($"Message: {ex.Message}"); Program.Chalker.WriteError(ex.StackTrace); } } } catch (Exception ex) { Program.Chalker.WriteError($"{ex.Message}\r\nStackTrace:{ex.StackTrace}"); } }
public static Dictionary <string, List <AttributeData> > FindAndInvokeAllAttributes(List <AttributeData> allAttributes, OperationTimer timer) { var typelist = GetTypesInNamespace(Assembly.GetExecutingAssembly(), "UniversalUnityHooks.Attributes"); var returnData = new Dictionary <string, List <AttributeData> >(); long lastElapsedMs = 0; foreach (var type in typelist) { if (type.BaseType != typeof(Attributes.Attribute)) { continue; } var instance = Activator.CreateInstance(type, new object[] { allAttributes, timer }); if (GetAndInvokeAddAllFoundMethod(type, instance)) { continue; } var attributes = GetAttributeProperty(type, instance); if (attributes == null) { continue; } returnData.Add(type.Name, attributes); ConsoleHelper.WriteMessage($"Attributes found of type {type.Name}: {attributes.Count} ({timer.GetElapsedMs - lastElapsedMs}ms)"); lastElapsedMs = timer.GetElapsedMs; } return(returnData); }
public Dictionary <string, List <AttributeData> > InstantiateAndInvoke(List <AttributeData> foundAttributes, OperationTimer timer) { var returnData = new Dictionary <string, List <AttributeData> >(); long lastElapsedMs = 0; foreach (var type in Util.GetTypesInNamespace(Assembly.GetExecutingAssembly(), "UniversalUnityHooks.Attributes")) { if (type.BaseType != typeof(Attributes.Attribute)) { continue; } var instance = (Attributes.Attribute)Activator.CreateInstance(type, new object[] { foundAttributes, timer }); if (instance.AddAllFound() != AddAttributesResponse.Ok) { continue; } var attributes = instance.Attributes; if (attributes == null) { continue; } returnData.Add(type.Name, attributes); Program.Chalker.WriteMessage($"Attributes found of type {type.Name}: {attributes.Count} ({timer.GetElapsedMs - lastElapsedMs}ms)"); lastElapsedMs = timer.GetElapsedMs; } return(returnData); }
static void Main(string[] args) { waitForInput |= args.Contains("-waitforinput"); Console.WriteLine($"Universal Unity Hooks v{ver}"); var timer = new OperationTimer(); Util.CreateFiles(); managedFolder = GetManagedDirectory(); if (managedFolder == null) { if (waitForInput) { Console.ReadKey(); } Environment.Exit(-1); } targetAssembly = Path.Combine(managedFolder, targetAssembly); var TargetAssemblyClean = Path.Combine(managedFolder, targetAssembly + ".clean"); ConsoleHelper.WriteMessage($"Found target assembly: {targetAssembly}"); Console.WriteLine(); Assemblies.GetAllAssembliesInsideDirectory(pluginsFolder); Console.WriteLine(); // Improve var sum = Attributes.Sum(x => x.Value.Count); if (sum == 0) { ConsoleHelper.WriteError($"No attributes have been loaded in. Press any key to exit the program."); if (waitForInput) { Console.ReadKey(); } Environment.Exit(-1); } ConsoleHelper.WriteMessage(ConsoleHelper.MessageType.Success, $"Total of {sum} attribute(s) have been loaded in."); Console.WriteLine(); ConsoleHelper.WriteMessage(ConsoleHelper.MessageType.Wait, $"Loading target assembly.."); try { if (File.Exists(TargetAssemblyClean)) { File.Delete(targetAssembly); File.Copy(TargetAssemblyClean, targetAssembly); } else { File.Copy(targetAssembly, TargetAssemblyClean); } } catch (Exception ex) { ConsoleHelper.WriteError("Something went wrong while trying to get or copy the target assembly file."); ConsoleHelper.WriteError($"Message: {ex.Message}"); ConsoleHelper.WriteError(ex.StackTrace); if (waitForInput) { Console.ReadKey(); } Environment.Exit(-1); } var assemblyDefinition = Cecil.ReadAssembly(targetAssembly); if (assemblyDefinition == null) { ConsoleHelper.WriteError("Press any key to exit this program."); if (waitForInput) { Console.ReadKey(); } Environment.Exit(-1); } ConsoleHelper.WriteMessage(ConsoleHelper.MessageType.Success, $"Target assembly loaded in."); Console.WriteLine(); var injectedCorrectly = InjectAllHooks(Attributes, assemblyDefinition); Console.WriteLine(); if (injectedCorrectly == 0) { ConsoleHelper.WriteError($"No methods have been injected correctly. Please read above for more information why some injections may have failed."); } else { ConsoleHelper.WriteMessage(ConsoleHelper.MessageType.Success, $"Injected {(injectedCorrectly == sum ? $"all {sum}" : $"{injectedCorrectly}/{sum}")} methods. {(injectedCorrectly != sum ? "Please read above for more information why some injections may have failed." : "")}"); ConsoleHelper.WriteMessage(ConsoleHelper.MessageType.Wait, "Writing changes to target assembly.."); if (Cecil.WriteChanges(assemblyDefinition)) { ConsoleHelper.WriteMessage(ConsoleHelper.MessageType.Success, $"Changes have been written to the file {targetAssembly}!"); } }
public static void Main(string[] args) { Parser.Default.ParseArguments <Options>(args).WithParsed((options) => Options.Instance = options).WithNotParsed((_) => Util.Exit()); Console.WriteLine($"Universal Unity Hooks v{Version}"); Options.Instance.GetTargetAssembly(out var targetAssemblyName, out var targetAssemblyNameClean); TargetAssembly = targetAssemblyName; TargetAssemblyClean = targetAssemblyNameClean; PluginsFolder = Options.Instance.GetInputDirectory(); OutputFolder = Options.Instance.GetOutputDirectory(); Util.CreateFiles(); Chalker.WriteMessage($"Target assembly file: {TargetAssembly}"); Chalker.WriteMessage($"Target plugins & search directory: {PluginsFolder}"); Console.WriteLine(); var timer = new OperationTimer(); AssemblyHelper = new AssemblyHelper(PluginsFolder); AssemblyHelper.FetchAndLoadAll(); Console.WriteLine(); var sum = Attributes.Sum(x => x.Value.Count); if (sum == 0) { Chalker.WriteError("No attributes have been loaded in. Press any key to exit the program."); Util.Exit(); } Chalker.WriteSuccess($"Total of {sum} attribute(s) have been loaded in."); Console.WriteLine(); Chalker.WriteWait("Loading target assembly.."); try { if (File.Exists(TargetAssemblyClean)) { File.Delete(TargetAssembly); File.Copy(TargetAssemblyClean, TargetAssembly); } else { File.Copy(TargetAssembly, TargetAssemblyClean); } } catch (Exception ex) { Chalker.WriteError("Something went wrong while trying to get or copy the target assembly file."); Chalker.WriteError($"Message: {ex.Message}"); Chalker.WriteError(ex.StackTrace); Util.Exit(); } if (!Util.ReadAssembly(TargetAssembly, OutputFolder, out var assemblyDefinition)) { Chalker.WriteError("Press any key to exit this program."); Util.Exit(); } Chalker.WriteSuccess("Target assembly loaded in."); Console.WriteLine(); var injectedCorrectly = Util.InjectAllHooks(Attributes, assemblyDefinition); Console.WriteLine(); if (injectedCorrectly == 0) { Chalker.WriteError($"No methods have been injected correctly. Please read above for more information why some injections may have failed."); } else { Chalker.WriteSuccess($"Injected {(injectedCorrectly == sum ? $"all {sum}" : $"{injectedCorrectly}/{sum}")} methods. {(injectedCorrectly != sum ? "Please read above for more information why some injections may have failed." : "")}"); Chalker.WriteWait("Writing changes to target assembly.."); if (Cecil.WriteChanges(assemblyDefinition, TargetAssembly)) { Chalker.WriteSuccess($"Changes have been written to the file {TargetAssembly}!"); } }