Пример #1
0
        private static async Task <List <UserModule> > GetModulesFromDirectoriesParallelAsync(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);
        }
Пример #2
0
        /* 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);
        }
Пример #3
0
        /// <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();
        }
Пример #4
0
        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 GetModulesFromDirectoriesParallelAsync(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();
        }
Пример #5
0
        /// <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);
        }