Ejemplo n.º 1
0
        public void PreloadPlugins()
        {
            Stopwatch benchmark = Stopwatch.StartNew();

            Debugger.Module("Pre loading modules");
            string[] modules = Directory.GetDirectories(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Modules"));
            foreach (string module in modules)
            {
                // Skip modules without Module.json
                if (!File.Exists(Path.Combine(module, "module.json")))
                {
                    continue;
                }

                try
                {
                    string            serializedModule = File.ReadAllText(Path.Combine(module, "module.json"));
                    PluginInformation modInformation   = JsonConvert.DeserializeObject <PluginInformation>(serializedModule);
                    PluginSettings    modSettings      = GetPluginSettings(module);

                    if (File.Exists(Path.Combine(module, modInformation.EntryPoint)))
                    {
                        Debugger.Module($"Compiling plugin: {modInformation.Name}");
                        if (CompilePlugin(module, modInformation))
                        {
                            Debugger.Module($"{modInformation.Name} compiled successfully.");
                        }
                        else
                        {
                            continue;
                        }
                    }
                    Stopwatch s = Stopwatch.StartNew();
                    foreach (string required in modInformation.Dependencies)
                    {
                        AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, required)));
                    }
                    Assembly           plugin  = AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, $"{modInformation.Name}.dll")));
                    IEnumerable <Type> entries = plugin.ExportedTypes.Where(exp => exp.GetMethod("Initialize") != null);
                    if (entries.Count() > 0)
                    {
                        dynamic mod = plugin.CreateInstance(entries.First().ToString());
                        packages.Add(new PluginPackage {
                            plugin = mod, information = modInformation, settings = modSettings, path = module
                        });
                    }
                } catch (Exception err)
                {
                    Debugger.Error(err);
                    continue;
                }
            }
            IsReady = true;
            benchmark.Stop();
            Debugger.Module($"Pre loaded {packages.Count} module(s) in {benchmark.ElapsedMilliseconds}ms");
            if (QueueLoad)
            {
                LoadPlugins();
            }
        }
Ejemplo n.º 2
0
        public bool CompilePlugin(string pluginPath, PluginInformation information)
        {
            var compiler = CSharpCompilation.Create($"{nameof(HunterPie)}{information.Name}", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
                                                    .WithOptimizationLevel(OptimizationLevel.Release));

            var types = new[]
            {
                typeof(Hunterpie),               // HunterPie
                typeof(JObject),                 // Newtonsoft.Json.dll
                typeof(Object),                  // mscorlib.dll
                typeof(UIElement),               // PresentationCore.dll
                typeof(Window),                  // PresentationFramework.dll
                typeof(Uri),                     // System.dll
                typeof(Enumerable),              // System.Core.dll
                typeof(DataSet),                 // System.Data.dll
                typeof(DataTableExtensions),     // System.Data.DataSetExtensions.dll
                typeof(Bitmap),                  // System.Drawing.dll
                typeof(HttpClient),              // System.Net.Http.dll
                typeof(BigInteger),              // System.Numerics.dll
                typeof(Form),                    // System.Windows.Forms.dll
                typeof(XamlType),                // System.Xaml.dll
                typeof(XmlNode),                 // System.Xml.dll
                typeof(XNode),                   // System.Xml.Linq.dll
                typeof(Rect),                    // WindowsBase.dll
            };

            // Load all basic dependencies
            List <MetadataReference> references = types.Select(type => MetadataReference.CreateFromFile(type.Assembly.Location)).ToList <MetadataReference>();

            if (information.Dependencies != null)
            {
                foreach (string extDependency in information.Dependencies)
                {
                    references.Add(MetadataReference.CreateFromFile(Path.Combine(pluginPath, extDependency)));
                }
            }
            compiler = compiler.AddReferences(references);
            var code    = File.ReadAllText(Path.Combine(pluginPath, information.EntryPoint));
            var options = CSharpParseOptions.Default.WithLanguageVersion(
                LanguageVersion.CSharp7_3);
            var syntaxTree = SyntaxFactory.ParseSyntaxTree(SourceText.From(code, Encoding.UTF8), options, Path.Combine(pluginPath, information.EntryPoint));

            compiler = compiler.AddSyntaxTrees(syntaxTree);
            var result = compiler.Emit(Path.Combine(pluginPath, information.Name) + ".dll");

            if (result.Success)
            {
                return(true);
            }
            else
            {
                Debugger.Error($"Failed to compile plugin: {information.Name}");
                foreach (var exception in result.Diagnostics)
                {
                    Debugger.Error(exception);
                }
                return(false);
            }
        }
Ejemplo n.º 3
0
        public void LoadPlugins(Game ctx)
        {
            Stopwatch benchmark = Stopwatch.StartNew();

            if (plugins.Count > 0)
            {
                // Quick load
                foreach (IPlugin plugin in plugins)
                {
                    plugin.Initialize(ctx);
                }
            }
            else
            {
                string[] modules = Directory.GetDirectories(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Modules"));
                foreach (string module in modules)
                {
                    try
                    {
                        string            serializedModule = File.ReadAllText(Path.Combine(module, "module.json"));
                        PluginInformation modInformation   = JsonConvert.DeserializeObject <PluginInformation>(serializedModule);

                        if (File.Exists(Path.Combine(module, modInformation.EntryPoint)))
                        {
                            Debugger.Module($"Compiling plugin: {modInformation.Name}");
                            if (CompilePlugin(module, modInformation))
                            {
                                Debugger.Module($"{modInformation.Name} compiled successfully.");
                            }
                            else
                            {
                                continue;
                            }
                        }

                        foreach (string required in modInformation.Dependencies)
                        {
                            AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, required)));
                        }
                        var plugin = AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, $"{modInformation.Name}.dll")));
                        IEnumerable <Type> entries = plugin.ExportedTypes.Where(exp => exp.GetMethod("Initialize") != null);
                        if (entries.Count() > 0)
                        {
                            dynamic mod = plugin.CreateInstance(entries.First().ToString());
                            mod.Initialize(ctx);
                            plugins.Add(mod);
                        }
                    } catch (Exception err)
                    {
                        Debugger.Error(err);
                        continue;
                    }
                }
            }
            benchmark.Stop();
            Debugger.Module($"Loaded {plugins.Count} module(s) in {benchmark.ElapsedMilliseconds}ms");
        }
Ejemplo n.º 4
0
        public async Task <string> GetModuleUpdateUrl(PluginInformation pInformation)
        {
            if (await ShouldUseProxy())
            {
                return(BuildUrl(ConfigManager.Settings.HunterPie.PluginRegistryUrl, "plugin", Uri.EscapeUriString(pInformation.Name), "module"));
            }

            return(pInformation.Update.UpdateUrl);
        }
Ejemplo n.º 5
0
        public static async Task <bool> UpdateAllFiles(PluginInformation pInformation, string modPath)
        {
            string onlineSerializedInformation = await ReadOnlineModuleJson(pInformation.Update.UpdateUrl);

            if (onlineSerializedInformation is null)
            {
                //Debugger.Error($"Failed to update plugin: {pInformation.Name}!");
                return(false);
            }

            PluginInformation onlineInformation = JsonConvert.DeserializeObject <PluginInformation>(onlineSerializedInformation);

            if (!(Hunterpie.ParseVersion(Hunterpie.HUNTERPIE_VERSION) >= Hunterpie.ParseVersion(onlineInformation.Update.MinimumVersion)))
            {
                return(false);
            }

            foreach (string filePath in onlineInformation.Update.FileHashes.Keys)
            {
                string onlineHash = onlineInformation.Update.FileHashes[filePath];

                if (onlineHash.ToLower() == "installonly" && File.Exists(Path.Combine(modPath, filePath)))
                {
                    continue;
                }

                if (pInformation.Update.FileHashes.ContainsKey(filePath))
                {
                    string localHash = pInformation.Update.FileHashes[filePath];

                    if (onlineHash.ToLower() != localHash.ToLower() || !File.Exists(Path.Combine(modPath, filePath)))
                    {
                        string updateurl  = $"{pInformation.Update.UpdateUrl}/{filePath}";
                        string outputPath = Path.Combine(modPath, filePath);

                        if (!(await DownloadFileAsync(updateurl, outputPath, filePath)))
                        {
                            return(false);
                        }
                    }
                }
                else
                {
                    string updateurl  = $"{pInformation.Update.UpdateUrl}/{filePath}";
                    string outputPath = Path.Combine(modPath, filePath);
                    if (!(await DownloadFileAsync(updateurl, outputPath, filePath)))
                    {
                        return(false);
                    }
                }
            }
            return(await DownloadFileAsync($"{pInformation.Update.UpdateUrl}/module.json", Path.Combine(modPath, "module.json"), "module.json"));
        }
Ejemplo n.º 6
0
        public async Task <bool> PreloadPlugins()
        {
            Stopwatch benchmark = Stopwatch.StartNew();

            Debugger.Module("Pre loading modules");
            foreach (string module in IterateModules())
            {
                try
                {
                    string            serializedModule = File.ReadAllText(Path.Combine(module, "module.json"));
                    PluginInformation modInformation   = JsonConvert.DeserializeObject <PluginInformation>(serializedModule);

                    try
                    {
                        await PreloadPlugin(module, modInformation);

                        failedPlugins.Remove(modInformation.Name);
                    }
                    catch
                    {
                        failedPlugins.Add(modInformation.Name);
                        throw;
                    }
                }
                catch (Exception err)
                {
                    Debugger.Error(err);
                }
            }

            benchmark.Stop();
            Debugger.Module($"Pre loaded {packages.Count} module(s) in {benchmark.ElapsedMilliseconds}ms");

            if (!tsc.Task.IsCompleted)
            {
                tsc.SetResult(null);
            }
            return(true);
        }
Ejemplo n.º 7
0
        private async Task PreloadPlugin(string module, PluginInformation modInformation)
        {
            if (File.Exists(Path.Combine(module, ".remove")))
            {
                Directory.Delete(module, true);
                Debugger.Module($"Plugin {modInformation.Name} removed.");
                return;
            }

            if (modInformation.Update.MinimumVersion is null)
            {
                Debugger.Error($"{modInformation.Name.ToUpper()} MIGHT BE OUTDATED! CONSIDER UPDATING IT.");
            }

            if (PluginUpdate.PluginSupportsUpdate(modInformation))
            {
                switch (await PluginUpdate.UpdateAllFiles(modInformation, module))
                {
                case UpdateResult.Updated:
                    var serializedModule = File.ReadAllText(Path.Combine(module, "module.json"));
                    modInformation = JsonConvert.DeserializeObject <PluginInformation>(serializedModule);

                    Debugger.Module($"Updated plugin: {modInformation.Name} (ver {modInformation.Version})");
                    break;

                case UpdateResult.Skipped:
                    break;

                case UpdateResult.Failed:
                    Debugger.Error($"Failed to update plugin: {modInformation.Name}");
                    break;

                case UpdateResult.UpToDate:
                    Debugger.Module($"Plugin {modInformation.Name} is up-to-date (ver {modInformation.Version})");
                    break;
                }
            }

            PluginSettings modSettings = GetPluginSettings(module);

            if (!string.IsNullOrEmpty(modInformation.EntryPoint) &&
                File.Exists(Path.Combine(module, modInformation.EntryPoint)))
            {
                Debugger.Module($"Compiling plugin: {modInformation.Name}");
                if (CompilePlugin(module, modInformation))
                {
                    Debugger.Module($"{modInformation.Name} compiled successfully.");
                }
                else
                {
                    return;
                }
            }

            foreach (string required in modInformation.Dependencies)
            {
                AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, required)));
            }

            Assembly plugin =
                AppDomain.CurrentDomain.Load(
                    AssemblyName.GetAssemblyName(Path.Combine(module, $"{modInformation.Name}.dll")));
            IEnumerable <Type> entries = plugin.ExportedTypes.Where(exp => exp.GetMethod("Initialize") != null);

            if (entries.Any())
            {
                dynamic mod = plugin.CreateInstance(entries.First().ToString());
                packages.Add(new PluginPackage
                {
                    plugin = mod, information = modInformation, settings = modSettings, path = module
                });
            }
        }
Ejemplo n.º 8
0
        private async Task PreloadPlugin(string module, PluginInformation modInformation)
        {
            if (File.Exists(Path.Combine(module, ".remove")))
            {
                Directory.Delete(module, true);
                Debugger.Module($"Plugin {modInformation.Name} removed.");
                return;
            }

            if (modInformation.Update.MinimumVersion is null)
            {
                Debugger.Error($"{modInformation.Name.ToUpper()} MIGHT BE OUTDATED! CONSIDER UPDATING IT.");
            }

            if (PluginUpdate.PluginSupportsUpdate(modInformation))
            {
                switch (await PluginUpdate.UpdateAllFiles(modInformation, module))
                {
                case UpdateResult.Updated:
                    var serializedModule = File.ReadAllText(Path.Combine(module, "module.json"));
                    modInformation = JsonConvert.DeserializeObject <PluginInformation>(serializedModule);

                    Debugger.Module($"Updated plugin: {modInformation.Name} (ver {modInformation.Version})");
                    break;

                case UpdateResult.Skipped:
                    break;

                case UpdateResult.Failed:
                    Debugger.Error($"Failed to update plugin: {modInformation.Name}");
                    break;

                case UpdateResult.UpToDate:
                    Debugger.Module($"Plugin {modInformation.Name} is up-to-date (ver {modInformation.Version})");
                    break;
                }
            }

            PluginSettings modSettings = GetPluginSettings(module);

            if (!string.IsNullOrEmpty(modInformation.EntryPoint) &&
                File.Exists(Path.Combine(module, modInformation.EntryPoint)))
            {
                Debugger.Module($"Compiling plugin: {modInformation.Name}");
                if (CompilePlugin(module, modInformation))
                {
                    Debugger.Module($"{modInformation.Name} compiled successfully.");
                }
                else
                {
                    return;
                }
            }

            foreach (string required in modInformation.Dependencies)
            {
                AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, required)));
            }

            var moduleAssembly = AppDomain.CurrentDomain.Load(
                AssemblyName.GetAssemblyName(Path.Combine(module, $"{modInformation.Name}.dll"))
                );
            var pluginType = moduleAssembly.ExportedTypes.FirstOrDefault(exp => exp.GetMethod("Initialize") != null);

            if (pluginType != null)
            {
                var plugin = (IPlugin)moduleAssembly.CreateInstance(pluginType.FullName);
                // making sure that name is matching modInformation, e.g. if plugin dev forgot to populate this value
                plugin.Name = modInformation.Name;

                var package = new PluginPackage
                {
                    plugin = plugin, information = modInformation, settings = modSettings, path = module
                };
                packages.Add(package);

                // if plugin is enabled, adding it's settings
                if (modSettings.IsEnabled)
                {
                    AddPackageSettings(package);
                }
            }
        }
Ejemplo n.º 9
0
        public static async Task <UpdateResult> UpdateAllFiles(PluginInformation pInformation, string modPath)
        {
            var updateUrl = await PluginRegistryService.Instance.GetModuleUpdateUrl(pInformation);

            string onlineSerializedInformation = await ReadOnlineModuleJson(updateUrl);

            if (onlineSerializedInformation is null)
            {
                //Debugger.Error($"Failed to update plugin: {pInformation.Name}!");
                return(UpdateResult.Failed);
            }

            PluginInformation onlineInformation = JsonConvert.DeserializeObject <PluginInformation>(onlineSerializedInformation);

            if (!IsVersionOk(onlineInformation.Update.MinimumVersion))
            {
                Debugger.Warn($"Newest version of {pInformation.Name} requires HunterPie v{onlineInformation.Update.MinimumVersion}!");
                return(UpdateResult.Skipped);
            }

            UpdateResult result = UpdateResult.UpToDate;

            foreach (string filePath in onlineInformation.Update.FileHashes.Keys)
            {
                string onlineHash = onlineInformation.Update.FileHashes[filePath];

                if (onlineHash.ToLower() == "installonly" && File.Exists(Path.Combine(modPath, filePath)))
                {
                    continue;
                }

                if (pInformation.Update.FileHashes.ContainsKey(filePath))
                {
                    string localHash = pInformation.Update.FileHashes[filePath];

                    if (onlineHash.ToLower() != localHash.ToLower() || !File.Exists(Path.Combine(modPath, filePath)))
                    {
                        string outputPath = Path.Combine(modPath, filePath);
                        if (!(await DownloadFileAsync($"{updateUrl}/{filePath}", outputPath, filePath)))
                        {
                            return(UpdateResult.Failed);
                        }

                        result = UpdateResult.Updated;
                    }
                }
                else
                {
                    string outputPath = Path.Combine(modPath, filePath);
                    if (!(await DownloadFileAsync($"{updateUrl}/{filePath}", outputPath, filePath)))
                    {
                        return(UpdateResult.Failed);
                    }
                    result = UpdateResult.Updated;
                }
            }

            return(await DownloadFileAsync($"{updateUrl}/module.json", Path.Combine(modPath, "module.json"), "module.json")
                ? result
                : UpdateResult.Failed);
        }
Ejemplo n.º 10
0
 public static bool PluginSupportsUpdate(PluginInformation pluginInformation)
 {
     return(!string.IsNullOrEmpty(pluginInformation.Update.UpdateUrl));
 }
Ejemplo n.º 11
0
        public async Task <bool> PreloadPlugins()
        {
            Stopwatch benchmark = Stopwatch.StartNew();

            Debugger.Module("Pre loading modules");
            string[] modules = Directory.GetDirectories(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Modules"));
            foreach (string module in modules)
            {
                // Skip modules without Module.json
                if (!File.Exists(Path.Combine(module, "module.json")))
                {
                    continue;
                }

                try
                {
                    string            serializedModule = File.ReadAllText(Path.Combine(module, "module.json"));
                    PluginInformation modInformation   = JsonConvert.DeserializeObject <PluginInformation>(serializedModule);

                    if (modInformation.Update.MinimumVersion is null)
                    {
                        Debugger.Error($"{modInformation.Name.ToUpper()} MIGHT BE OUTDATED! CONSIDER UPDATING IT.");
                    }

                    if (PluginUpdate.PluginSupportsUpdate(modInformation))
                    {
                        switch (await PluginUpdate.UpdateAllFiles(modInformation, module))
                        {
                        case UpdateResult.Updated:
                            serializedModule = File.ReadAllText(Path.Combine(module, "module.json"));
                            modInformation   = JsonConvert.DeserializeObject <PluginInformation>(serializedModule);

                            Debugger.Module($"Updated plugin: {modInformation.Name} (ver {modInformation.Version})");
                            break;

                        case UpdateResult.Skipped:
                            break;

                        case UpdateResult.Failed:
                            Debugger.Error($"Failed to update plugin: {modInformation.Name}");
                            continue;

                        case UpdateResult.UpToDate:
                            Debugger.Module($"Plugin {modInformation.Name} is up-to-date (ver {modInformation.Version})");
                            break;
                        }
                    }

                    PluginSettings modSettings = GetPluginSettings(module);

                    if (!string.IsNullOrEmpty(modInformation.EntryPoint) && File.Exists(Path.Combine(module, modInformation.EntryPoint)))
                    {
                        Debugger.Module($"Compiling plugin: {modInformation.Name}");
                        if (CompilePlugin(module, modInformation))
                        {
                            Debugger.Module($"{modInformation.Name} compiled successfully.");
                        }
                        else
                        {
                            continue;
                        }
                    }
                    Stopwatch s = Stopwatch.StartNew();
                    foreach (string required in modInformation.Dependencies)
                    {
                        AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, required)));
                    }
                    Assembly           plugin  = AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, $"{modInformation.Name}.dll")));
                    IEnumerable <Type> entries = plugin.ExportedTypes.Where(exp => exp.GetMethod("Initialize") != null);
                    if (entries.Count() > 0)
                    {
                        dynamic mod = plugin.CreateInstance(entries.First().ToString());
                        packages.Add(new PluginPackage {
                            plugin = mod, information = modInformation, settings = modSettings, path = module
                        });
                    }
                }
                catch (Exception err)
                {
                    Debugger.Error(err);
                    continue;
                }
            }

            IsReady = true;
            benchmark.Stop();
            Debugger.Module($"Pre loaded {packages.Count} module(s) in {benchmark.ElapsedMilliseconds}ms");
            if (QueueLoad)
            {
                LoadPlugins();
            }
            return(true);
        }