private static async Task <List <UserModule> > GetModulesFromDirectoriesAsync(string[] directories) { var modTasks = directories.Where(dir => !dir.EndsWith("...ignore")).Select(async dir => { var files = Directory.GetFiles(dir, "*.dll", SearchOption.AllDirectories); UserModule mod = null; try { foreach (var file in files) { var asm = Assembly.LoadFrom(file); if (mod != null) { goto foundMod; } var startClasses = asm.GetTypes().Where(t => t.IsClass && t.BaseType == typeof(ModuleAPI.Module) && t.GetCustomAttribute <ApplicationHookAttribute>() != null ).ToList(); if (startClasses.Count <= 0) { continue; } var startupClass = startClasses[0]; mod = await UserModule.FromTypeAsync(startupClass); } foundMod: return(mod); } catch (Exception exc) { Logger.Log("Module loading error", exc); return(null); } }).ToList(); var foundModules = new List <UserModule>(); foreach (var modTask in modTasks) { if (modTask == null) { continue; } var um = await modTask; if (um != null) { foundModules.Add(um); } } return(foundModules); }
public static ModuleInfoPacket FromUserModule(UserModule mod) { return(new ModuleInfoPacket() { Name = mod.Name, Prefix = mod.Prefix, Commands = mod.RegisteredCommands }); }
private void SetupComponents(object sender, RoutedEventArgs e) { Closing += (o, args) => { Application.Current.Shutdown(); }; //Setup the command line interface Cmd = Cmd ?? CommandLine.GetInstance(); //Taskbar notification icon TaskbarIconManager.AddItem("Show", () => { ShowInTaskbar = true; Visibility = Visibility.Visible; Activate(); WindowState = WindowState.Maximized; }); TaskbarIconManager.AddItem("Exit", () => { Application.Current.Shutdown(0); }); TaskbarIconManager.CommitItems(); TaskbarIconManager.SetVisible(true); LoadedModules.SelectionChanged += LoadedModulesOnSelectionChanged; // Invokes commands recieved from TCP connections RemoteManager.CommandRecieved += (command, tcpClient) => { Task.Factory.StartNew(() => { UserModule mod = null; Command cm = null; if (UserModule.FindResponsibleUserModule(command, out mod, out cm, tcpClient)) { Dispatcher.Invoke(() => { Status = $"{(tcpClient != null ? (tcpClient.Client.RemoteEndPoint + " > ") : "")} [{mod.Name}:{mod.Prefix}] > {cm.LocalCommand}"; mod.GiveRegexCommand(cm); }); } }); }; RemoteManager.ClientConnected += client => { Dispatcher.Invoke(() => { Status = $"({client.Client.RemoteEndPoint}) has connected!"; }); }; RemoteManager.ClientDisconnected += client => { Dispatcher.Invoke(() => { Status = $"({client.Client.RemoteEndPoint}) has disconnected."; }); }; Command.Responded += (response, com, client) => { Dispatcher.Invoke(() => { Status = $"{((com != null && com != Command.Empty) ? $"[{com?.UserModuleName}] > " : "")}{response}"; }); }; }
/* STATIC METHODS */ /// <summary> /// Find the user module responsible for handling the user input based on which Regex matched /// </summary> /// <param name="query">User input</param> /// <param name="selectedModule">Module responsible for handling the query</param> /// <param name="command">The command that was detected from user input</param> /// <param name="client">Was it a remote command?</param> /// <returns></returns> public static bool FindResponsibleUserModule(string query, out UserModule selectedModule, out Command command, TcpClient client = null) { selectedModule = null; command = null; if (string.IsNullOrWhiteSpace(query)) { return(false); } var selectedRegexKey = ""; var matchFound = false; var m = Regex.Match(query, "^(?<first>.+?)\\s+(?<rest>.+)$"); var firstWord = m.Groups["first"].Value; var rest = m.Groups["rest"].Value; var shortListModule = ModuleLoader.ModuleLoadOrder.Values.FirstOrDefault(val => val.Prefix == firstWord); if (shortListModule != null && shortListModule.Enabled) { foreach (var rgxs in shortListModule.RegisteredCommands) { if (matchFound) { break; } if (rgxs.Value.Match(rest).Success) { selectedRegexKey = rgxs.Key; selectedModule = shortListModule; matchFound = true; break; } } } //If a match is not found or the user input is invalid, select all user input text if (!matchFound || selectedModule == null || string.IsNullOrWhiteSpace(selectedRegexKey)) { return(false); } command = new Command(shortListModule.Prefix, shortListModule.RegisteredCommands[selectedRegexKey], rest, selectedRegexKey, client); return(true); }
private void InitiateCommand() { var query = Input.Text; //_cmdInstance.Hide(); Task.Run(() => { UserModule um = null; Command cm = null; if (UserModule.FindResponsibleUserModule(query, out um, out cm)) { Dispatcher.Invoke(() => { um.GiveRegexCommand(cm); _commandHistory.Add(cm.ToString()); }); } }); }
/// <summary> /// Load all modules in the Module Directory /// </summary> public static void LoadAll() { ModuleLoadOrder = ModuleLoadOrder ?? new Dictionary <int, UserModule>(); ModuleLoadOrder?.Clear(); var sysModule = UserModule.FromType(typeof(SystemCommands)); ModuleLoadOrder.Add(ModuleLoadOrder.Count, sysModule); var directories = Directory.GetDirectories(ModuleDirectory, "*", SearchOption.TopDirectoryOnly); LoadingStarted?.Invoke(directories.Length); // Search through all directories and add user modules directories.ToList().ForEach(dir => { var um = GetModuleFromDirectory(dir); // If a module is detected, add it to the ModuleLoadOrder dictionary if (um != null) { var index = ModuleLoadOrder.Count + 1; var canUse = false; do { if (!ModuleLoadOrder.ContainsKey(index)) { canUse = true; ModuleLoadOrder.Add(index, um); ModuleLoaded?.Invoke(um); } else { index++; } } while(canUse == false); } }); LoadingEnded?.Invoke(); }
public static async Task LoadAllAsync() { ModuleLoadOrder = ModuleLoadOrder ?? new Dictionary <int, UserModule>(); ModuleLoadOrder?.Clear(); var sysModule = await UserModule.FromTypeAsync(typeof(SystemCommands)); ModuleLoadOrder.Add(ModuleLoadOrder.Count, sysModule); var directories = Directory.GetDirectories(ModuleDirectory, "*", SearchOption.TopDirectoryOnly); LoadingStarted?.Invoke(directories.Length); var foundModules = await GetModulesFromDirectoriesAsync(directories); foundModules.ForEach(um => { var index = ModuleLoadOrder.Count + 1; var canUse = false; do { if (!ModuleLoadOrder.ContainsKey(index)) { canUse = true; ModuleLoadOrder.Add(index, um); ModuleLoaded?.Invoke(um); } else { index++; } } while(canUse == false); }); LoadingEnded?.Invoke(); }
/// <summary> /// Load a module anywhere inside a specific directory /// </summary> /// <param name="directory">Location of the module</param> /// <returns></returns> private static UserModule GetModuleFromDirectory(string directory) { var files = Directory.EnumerateFiles(directory, "*.dll", SearchOption.AllDirectories); UserModule mod = null; // Load each *.dll file found in the directory files.ToList().ForEach(async file => { try { var asm = Assembly.LoadFrom(file); // Search for a type in the loaded assembly that:- // 1. Is a child of the Module class // 2. Has the ApplicationHook attribute (that can only be applied to one class) var startClasses = asm.GetTypes().Where(t => t.IsClass && t.BaseType == typeof(ModuleAPI.Module) && t.GetCustomAttribute <ApplicationHookAttribute>() != null ).ToList(); // If any class meeting these conditions is found, // Store that as the 'Startup Class' i.e. the class // which will recieve commands through Project Butler if (startClasses.Count > 0) { var startupClass = startClasses[0]; mod = await UserModule.FromTypeAsync(startupClass); } } catch (Exception exc) { Logger.Log("Module loading error", exc); } }); return(mod); }