Пример #1
0
        /// <summary>
        ///     Removes a Package from the Plugin System
        /// </summary>
        /// <param name="ptr">Pointer Pointing to the Package that should be removed.</param>
        /// <param name="keepArchive">When set to false will also delete the backup archive.</param>
        internal static void RemovePackage(BasePluginPointer ptr, bool keepArchive = true)
        {
            //TODO: Check if the Package is in the Installed List. Then we need to wait until the program restarted.

            List <string> installedPackages = ListHelper.LoadList(PluginPaths.GlobalPluginListFile).ToList();
            string        package           = ptr.ToKeyPair();

            if (installedPackages.Contains(package))
            {
                RemovePackageEventArgs args = new RemovePackageEventArgs(ptr, keepArchive, true);
                OnRemovePackage?.Invoke(args);
                if (args.Cancel)
                {
                    return;
                }

                keepArchive = args.KeepArchive;

                installedPackages.Remove(package);
                ListHelper.SaveList(PluginPaths.GlobalPluginListFile, installedPackages.ToArray());
                AfterRemovePackage?.Invoke(new RemovePackageEventArgs(ptr, keepArchive, false));
            }

            PluginPaths.RemovePluginPackageFromDirectoryStructure(ptr, keepArchive);
        }
Пример #2
0
        private void btnUnpack_Click(object sender, EventArgs e)
        {
            string tempDir = Path.Combine(PluginPaths.GetPluginTempDirectory(Pointer), "TempUnpack");

            if (Directory.Exists(tempDir))
            {
                Directory.Delete(tempDir, true);
            }

            Directory.CreateDirectory(tempDir);
            rtbInputInfo.Text = "";
            try
            {
                rtbInputInfo.Text += "Unpacking: ";
                PluginPacker.Unpack(tbInputDir.Text, tempDir);
                rtbInputInfo.Text += "SUCCESS\nReading Data Format: ";
                unpackedInputPath  = tempDir;
                inputPtr           = PackageDataManager.LoadData(tempDir);
                rtbInputInfo.Text += "SUCCESS";
                panelPack.Enabled  = true;
            }
            catch (Exception exception)
            {
                Directory.Delete(tempDir, true);
                rtbInputInfo.Text += "FAILED\n";
            }
        }
Пример #3
0
 /// <summary>
 ///     Creates all required directories for the Specified Plugin
 /// </summary>
 /// <param name="data">The Pointer Data</param>
 public static void EnsureDirectoriesExist(this BasePluginPointer data)
 {
     Directory.CreateDirectory(GetPluginDirectory(data));
     Directory.CreateDirectory(GetPluginConfigDirectory(data));
     Directory.CreateDirectory(GetPluginAssemblyDirectory(data));
     Directory.CreateDirectory(InternalConfigurationDirectory);
     Directory.CreateDirectory(GetPluginTempDirectory(data));
 }
Пример #4
0
        public override void Unpack(string file, string outputDirectory)
        {
            BasePluginPointer ptr    = WebPointerUpdateChecker.GetPointer(file);
            string            zip    = WebPointerUpdateChecker.DownloadFile(ptr);
            ZipPackerFormat   packer = new ZipPackerFormat();

            packer.Unpack(zip, outputDirectory);
            File.Delete(zip);
        }
Пример #5
0
        /// <summary>
        ///     Installs the Specified folder contents into the Directories of the specified pointer
        /// </summary>
        /// <param name="ptr">The Pointer</param>
        /// <param name="folder">The Folder with contents</param>
        public static void Install(BasePluginPointer ptr, string folder)
        {
            APackageDataFormat format = PackerMap.FirstOrDefault(x => x.CanLoad(folder));

            PluginManager.SendLog(
                $"Installing Package {ptr.PluginName} from {Path.GetFileName(folder)} with format {format.GetType().Name}"
                );
            format?.Install(ptr, folder);
        }
        public static string DownloadFile(BasePluginPointer ptr)
        {
            string tempFile = Path.Combine(
                PluginPaths.SystemTempDirectory,
                $"{ptr.PluginName}_{ptr.PluginVersion}_.zip"
                );

            DownloadFile(ptr, tempFile);
            return(tempFile);
        }
Пример #7
0
        /// <summary>
        ///     Deletes all directories of the Specified Plugin
        /// </summary>
        /// <param name="data">The Pointer Data</param>
        /// <param name="keepArchive">If true will not Delete the backup archive</param>
        public static void RemovePluginPackageFromDirectoryStructure(BasePluginPointer data, bool keepArchive)
        {
            Directory.Delete(GetPluginDirectory(data), true);
            Directory.Delete(GetPluginTempDirectory(data), true);

            //if (keepArchive && HasArchiveBackup(data))
            //{
            //    File.Delete(GetPluginArchiveBackup(data));
            //}
        }
Пример #8
0
        public static void CheckAndUpdate(
            BasePluginPointer ptr, Func <string, string, bool> updateDialog, Action <string, int, int> setStatus)
        {
            if (Checker.All(x => !x.CanCheck(ptr)))
            {
                return;
            }

            PluginManager.SendLog("Updating Plugin: " + ptr.PluginName);
            Checker.First(x => x.CanCheck(ptr)).CheckAndUpdate(ptr, updateDialog, setStatus);
        }
        public bool CanCheck(BasePluginPointer ptr)
        {
            if (ptr.PluginOrigin == "" || !ptr.PluginOrigin.EndsWith("info.txt"))
            {
                return(false);
            }

            Uri origin = ptr.PluginOriginUri;

            return(IsWebPointer(origin));
        }
        public bool CanCheck(BasePluginPointer ptr)
        {
            if (ptr.PluginOrigin == "" || !ptr.PluginOrigin.EndsWith(".dll"))
            {
                return(false);
            }

            Uri origin = ptr.PluginOriginUri;

            return(origin.Scheme == "file" &&
                   File.Exists(PluginPaths.GetPluginAssemblyFile(ptr)) &&
                   File.Exists(ptr.PluginOrigin));
        }
 public static void DownloadFile(BasePluginPointer ptr, string file)
 {
     using (WebClient wc = new WebClient())
     {
         string uri = ptr.PluginOriginUri.AbsoluteUri.Remove(
             ptr.PluginOriginUri.AbsoluteUri.Length -
             "info.txt".Length,
             "info.txt".Length
             ) +
                      ptr.PluginName +
                      ".zip";
         wc.DownloadFile(uri, file);
     }
 }
Пример #12
0
        public override void Install(BasePluginPointer ptr, string folder)
        {
            string cdir = GetConfigDir(folder);
            string bdir = GetBinPath(folder);

            if (Directory.Exists(cdir))
            {
                HelperClass.CopyTo(cdir, PluginPaths.GetPluginConfigDirectory(ptr));
            }

            if (Directory.Exists(bdir))
            {
                HelperClass.CopyTo(bdir, PluginPaths.GetPluginAssemblyDirectory(ptr));
            }
        }
Пример #13
0
        /// <summary>
        ///     Activates a Package in the Plugin System.
        /// </summary>
        /// <param name="packageName">The Package to be activated.</param>
        /// <param name="addToExistingHosts">When True will add all plugins in the Package to Compatible Loaded Hosts.</param>
        internal static void ActivatePackage(string packageName, bool addToExistingHosts = false)
        {
            List <BasePluginPointer> globalPackages =
                ListHelper.LoadList(PluginPaths.GlobalPluginListFile).Select(x => new BasePluginPointer(x)).ToList();
            BasePluginPointer packageKey = globalPackages.FirstOrDefault(x => x.PluginName == packageName);

            if (packageKey != null)
            {
                List <string> installedPackages = ListHelper.LoadList(PluginPaths.PluginListFile).ToList();
                string        key = packageKey.ToKeyPair();

                if (!installedPackages.Contains(key))
                {
                    ActivatePackageEventArgs args = new ActivatePackageEventArgs(packageKey, true);
                    OnActivatePackage?.Invoke(args);
                    if (args.Cancel)
                    {
                        return;
                    }

                    installedPackages.Add(key);

                    ListHelper.SaveList(PluginPaths.PluginListFile, installedPackages.ToArray());
                    if (addToExistingHosts)
                    {
                        foreach (KeyValuePair <IPluginHost, List <IPlugin> > loadedPlugin in LoadedPlugins)
                        {
                            PluginAssemblyPointer ptr = new PluginAssemblyPointer(
                                packageKey.PluginName,
                                packageKey.PluginFile,
                                packageKey.PluginOrigin,
                                packageKey.PluginVersion.ToString(),
                                loadedPlugin.Key
                                );
                            PluginLoader.AddPluginsFromLoaderResult(ptr);
                        }
                    }

                    //UnloadPlugins(PluginHost);

                    //LoadPlugins(PluginHost);

                    AfterActivatePackage?.Invoke(new ActivatePackageEventArgs(packageKey, false));
                }
            }
        }
Пример #14
0
        /// <summary>
        ///     Deactivates a Package so its plugins are not considered when searching for compatible plugins for a Host.
        /// </summary>
        /// <param name="packageName">Name of package that should be deactivated.</param>
        internal static void DeactivatePackage(string packageName)
        {
            List <string>            list = ListHelper.LoadList(PluginPaths.PluginListFile).ToList();
            List <BasePluginPointer> installedPackages = list.Select(x => new BasePluginPointer(x)).ToList();
            BasePluginPointer        ptr = installedPackages.FirstOrDefault(x => x.PluginName == packageName);

            if (ptr != null)
            {
                DeactivatePackageEventArgs args = new DeactivatePackageEventArgs(ptr, true);
                OnDeactivatePackage?.Invoke(args);
                if (args.Cancel)
                {
                    return;
                }

                list.Remove(ptr.ToKeyPair());
                ListHelper.SaveList(PluginPaths.PluginListFile, list.ToArray());
                AfterDeactivatePackage?.Invoke(new DeactivatePackageEventArgs(ptr, false));
            }
        }
        public void CheckAndUpdate(
            BasePluginPointer ptr, Func <string, string, bool> updateDialog, Action <string, int, int> setStatus)
        {
            byte[] a   = File.ReadAllBytes(PluginPaths.GetPluginAssemblyFile(ptr));
            byte[] b   = File.ReadAllBytes(ptr.PluginOrigin);
            bool   ret = AreEqual(a, b);

            if (ret)
            {
                return;
            }

            if (!updateDialog(
                    $"The file '{ptr.PluginOrigin}' is a different version. Do you want to Update?",
                    "Update: " + ptr.PluginName
                    ))
            {
                return;
            }

            File.Copy(ptr.PluginOrigin, PluginPaths.GetPluginAssemblyFile(ptr), true);
        }
        public void CheckAndUpdate(
            BasePluginPointer ptr, Func <string, string, bool> updateDialog, Action <string, int, int> setStatus)
        {
            setStatus?.Invoke($"[{ptr.PluginName}] Searching Updates.", 0, 1);
            BasePluginPointer originPtr = GetPointer(ptr.PluginOrigin);

            if (ptr.PluginVersion >= originPtr.PluginVersion)
            {
                setStatus?.Invoke($"[{ptr.PluginName}] Up to date.", 1, 1);
                return;
            }

            setStatus?.Invoke($"[{ptr.PluginName}] Waiting for User Input", 1, 3);
            if (updateDialog(
                    $"Do you want to update {ptr.PluginName} : {ptr.PluginVersion} to {originPtr.PluginName} : {originPtr.PluginVersion}?",
                    $"Update: {originPtr.PluginVersion}"
                    ))
            {
                string tempFile = Path.Combine(
                    PluginPaths.GetPluginTempDirectory(ptr),
                    $"{originPtr.PluginName}_{originPtr.PluginVersion}_.zip"
                    );

                setStatus?.Invoke($"[{ptr.PluginName}] Installing Update", 1, 3);

                DownloadFile(originPtr, tempFile);

                PluginManager.AddPackage(tempFile, out string name);

                File.Delete(tempFile);
            }
            else
            {
                setStatus?.Invoke($"[{ptr.PluginName}] User denied update request.", 1, 3);
            }
        }
Пример #17
0
        private void ToggleLoadState(object sender, EventArgs e)
        {
            if (lbPlugins.SelectedIndex != -1)
            {
                if (lbPlugins.SelectedItem is IPlugin plugin)
                {
                }
                else
                {
                    bool isActive         = lbPluginHosts.SelectedItem.ToString() != "[Inactive Packages]";
                    BasePluginPointer ptr = new BasePluginPointer(lbPlugins.SelectedItem.ToString());
                    if (!isActive)
                    {
                        ActionRunner.AddActionToStartup($"{ActionRunner.ACTIVATE_PACKAGE_ACTION} {ptr.PluginName}");
                    }
                    else
                    {
                        ActionRunner.AddActionToStartup($"{ActionRunner.DEACTIVATE_PACKAGE_ACTION} {ptr.PluginName}");
                    }

                    lbPlugins.Items.Remove(lbPlugins.SelectedItem);
                }
            }
        }
 public AfterAddPackageEventArgs(BasePluginPointer pointer) : base(false)
 {
     Pointer = pointer;
 }
 public ActivatePackageEventArgs(BasePluginPointer packagePtr, bool canCancel) : base(canCancel)
 {
     PackagePointer = packagePtr;
 }
Пример #20
0
 public override void SaveData(BasePluginPointer data, string outputFolder)
 {
     File.WriteAllText(GetDataPath(outputFolder), data.ToKeyPair());
 }
Пример #21
0
        /// <summary>
        ///     Adds a Package to the Plugin System
        /// </summary>
        /// <param name="file">Package Input Path</param>
        /// <param name="name">When Loaded successfully contains the Name of the Loaded plugin</param>
        /// <returns>True if the Adding was Successful</returns>
        internal static bool AddPackage(string file, out string name)
        {
            if (!IsInitialized)
            {
                throw new Exception("Can not use the plugin System when its not initialized.");
            }

            name = null;
            SendLogDivider();
            SendLog("Adding File: " + file);


            if (PluginPacker.CanLoad(file))
            {
                AddPackageEventArgs <string> args = new AddPackageEventArgs <string>(file, true);
                OnAddPackage?.Invoke(args);
                if (args.Cancel)
                {
                    return(false);
                }

                string tempDir = Path.Combine(
                    PluginPaths.GetSystemProcessTempDirectory("Install"),
                    Path.GetFileNameWithoutExtension(Path.GetRandomFileName())
                    );                          //TODO: Get temp dir for unpacking
                Directory.CreateDirectory(tempDir);

                //TODO: If the package is already installed Write Backup to PluginDir/backup before loading the new package

                SendLog("Trying to Load File Format: " + Path.GetFileName(file));
                PluginPacker.Unpack(file, tempDir);

                //TODO: Try load Package Data/Plugin Data
                if (PackageDataManager.CanLoad(tempDir))
                {
                    SendLog("Trying to Load Data Format: " + Path.GetFileName(tempDir));
                    BasePluginPointer ptr = PackageDataManager.LoadData(tempDir);
                    if (ptr != null)
                    {
                        name = ptr.PluginName;
                        ptr.EnsureDirectoriesExist();

                        AddPackageEventArgs <BasePluginPointer> ptrArgs =
                            new AddPackageEventArgs <BasePluginPointer>(ptr, true);
                        OnAddPackagePointerLoaded?.Invoke(ptrArgs);
                        if (ptrArgs.Cancel)
                        {
                            return(false);
                        }

                        List <string> installedPackages = ListHelper.LoadList(PluginPaths.GlobalPluginListFile).ToList();
                        List <string> activePackages    = ListHelper.LoadList(PluginPaths.PluginListFile).ToList();
                        string        newPackage        = ptr.ToKeyPair();
                        bool          isNew             = installedPackages.All(x => !x.StartsWith(ptr.PluginName));
                        if (isNew)
                        {
                            installedPackages.Add(newPackage);
                        }
                        else
                        {
                            if (activePackages.RemoveAll(x => x.StartsWith(ptr.PluginName)) != 0)
                            {
                                activePackages.Add(newPackage);
                                ListHelper.SaveList(PluginPaths.PluginListFile, activePackages.ToArray());
                            }

                            installedPackages.RemoveAll(x => x.StartsWith(ptr.PluginName));
                            installedPackages.Add(newPackage);
                        }

                        ListHelper.SaveList(PluginPaths.GlobalPluginListFile, installedPackages.ToArray());

                        //TODO: Check if the Install would overwrite things.
                        //TODO: Check if the files that are overwritten are in use.
                        //TODO: Make a system that takes instructions from a file at start up to "complete" installations
                        InstallPackageEventArgs iargs = new InstallPackageEventArgs(isNew, ptr, tempDir, true);
                        OnInstallPackage?.Invoke(iargs);
                        if (iargs.Cancel)
                        {
                            return(false);
                        }

                        PackageDataManager.Install(ptr, tempDir);

                        Directory.Delete(tempDir, true);

                        AfterInstallPackage?.Invoke(new InstallPackageEventArgs(isNew, ptr, tempDir, false));

                        AfterAddPackage?.Invoke(new AfterAddPackageEventArgs(ptr));
                        return(true);
                    }

                    SendError(new PackageDataException("File Corrupt", file));
                }
                else
                {
                    SendError(new PackageDataException("Unable to find a Data Serializer", file, null));
                }
            }
            else
            {
                SendError(new PackerException("Unable to find a Packer", file, null));
            }

            return(false);
        }
Пример #22
0
 public RemovePackageEventArgs(BasePluginPointer pointer, bool keepArchive, bool canCancel) : base(canCancel)
 {
     KeepArchive = keepArchive;
     PointerData = pointer;
 }
Пример #23
0
 /// <summary>
 ///     Returns the Full Path to the Assembly File of the Plugin
 /// </summary>
 /// <param name="data">The plugin Data</param>
 /// <returns>Plugin Assembly File</returns>
 public static string GetPluginAssemblyFile(BasePluginPointer data)
 {
     return(GetPluginAssemblyFile(data.PluginName, data.PluginFile));
 }
Пример #24
0
 /// <summary>
 ///     Returns the Full Path to the Plugin Temp Directory
 /// </summary>
 /// <param name="data">The Pointer Data</param>
 /// <returns>Plugin Temp Directory</returns>
 public static string GetPluginTempDirectory(BasePluginPointer data)
 {
     return(GetPluginTempDirectory(data.PluginName));
 }
Пример #25
0
        public void Run(string[] args)
        {
            Debug.OnConfigCreate += ProjectDebugConfig_OnConfigCreate;

            Runner r = new Runner();

            r._AddCommand(new DefaultHelpCommand());
            r._AddCommand(
                new SetDataCommand(
                    strings => PackageAdds = strings,
                    new[] { "--add", "-a" },
                    "Adds a Plugin package by name"
                    )
                );
            r._AddCommand(
                new SetDataCommand(
                    strings => PackageAdds = strings,
                    new[] { "--add-activate", "-aa" },
                    "Adds and activates a Plugin package by name"
                    )
                );
            r._AddCommand(
                new SetDataCommand(
                    strings => PackageRemoves = strings,
                    new[] { "--remove", "-r" },
                    "Removes a Plugin package by name"
                    )
                );
            r._AddCommand(
                new SetDataCommand(
                    strings => PackageActivates = strings,
                    new[] { "--activate", "-active" },
                    "Activates a Plugin package by name"
                    )
                );
            r._AddCommand(
                new SetDataCommand(
                    strings => PackageDeactivates = strings,
                    new[] { "--deactivate", "-d" },
                    "Deactivates a Plugin package by name"
                    )
                );
            r._AddCommand(
                new SetDataCommand(
                    strings => OriginRemoves = strings,
                    new[] { "--remove-origin", "-ro" },
                    "Removes an Origin Url from the Origins File"
                    )
                );
            r._AddCommand(
                new SetDataCommand(
                    strings => OriginAdds = strings,
                    new[] { "--add-origin", "-ao" },
                    "Adds an Origin Url to the Origins File"
                    )
                );
            r._AddCommand(
                new SetDataCommand(
                    strings => DefaultOrigin = true,
                    new[] { "--default-origin", "-default" },
                    "Writes the Default Origin File to Disk, overwriting the current origin file"
                    )
                );
            r._AddCommand(
                new SetDataCommand(
                    strings => InstallAll = true,
                    new[] { "--all", "-all" },
                    "Installs and activates All packages from all repositories"
                    )
                );
            r._AddCommand(
                new SetDataCommand(
                    strings => ListPackages = true,
                    new[] { "--list-packages", "-list" },
                    "Lists All packages from all repositories"
                    )
                );
            r._AddCommand(
                new SetDataCommand(
                    strings => Verbosity = int.Parse(strings.First()),
                    new[] { "--verbosity", "-v" },
                    "The Verbosity Level (lower = less logs)"
                    )
                );


            FLData.InitializePluginSystemOnly(true);


            r._RunCommands(args);

            if (DefaultOrigin)
            {
                string file = RepositoryPlugin.GetOriginFilePath(GetDefaultRepoPluginPointer());
                Directory.CreateDirectory(Path.GetDirectoryName(file));
                WriteDefaultOrigin(file);
            }
            else
            {
                CheckOriginsExists(GetDefaultRepoPluginPointer());
            }

            RepositoryPlugin repo = GetPlugin();

            List <Repository> repos = repo.GetPlugins();
            IEnumerable <BasePluginPointer> global =
                ListHelper.LoadList(PluginPaths.GlobalPluginListFile).Select(x => new BasePluginPointer(x));
            IEnumerable <BasePluginPointer> active =
                ListHelper.LoadList(PluginPaths.PluginListFile).Select(x => new BasePluginPointer(x));

            if (ListPackages)
            {
                Console.WriteLine("Available Packages: ");
                foreach (Repository repository in repos)
                {
                    Console.WriteLine($"\tRepository: {repository.RepositoryOrigin}");
                    foreach (BasePluginPointer basePluginPointer in repository.Plugins)
                    {
                        BasePluginPointer installedPtr =
                            global.FirstOrDefault(x => x.PluginOrigin == basePluginPointer.PluginOrigin);
                        bool   contained = installedPtr != null;
                        bool   installed = contained && active.Any(x => x.PluginOrigin == basePluginPointer.PluginOrigin);
                        string tag       = installed ? "[ACTIVE]" : contained ? "[INSTALLED]" : "[NOT INSTALLED]";
                        Console.WriteLine($"\t\t{tag} {basePluginPointer.PluginName}");
                        Console.WriteLine($"\t\t\tVersion(Origin): {basePluginPointer.PluginVersion}");
                        Console.WriteLine(
                            $"\t\t\tVersion(Installed): {installedPtr?.PluginVersion?.ToString() ?? "NOT INSTALLED"}"
                            );
                    }
                }
            }

            if (InstallAll)
            {
                PackageAddsActivates = repos.SelectMany(x => x.Plugins.Select(y => y.PluginName)).ToArray();
            }

            foreach (string originRemove in OriginRemoves)
            {
                repo.RemoveOrigin(originRemove);
            }

            foreach (string originAdd in OriginAdds)
            {
                repo.AddOrigin(originAdd);
            }

            foreach (string packageDeactivate in PackageDeactivates)
            {
                ActionRunner.AddActionToStartup($"{ActionRunner.DEACTIVATE_PACKAGE_ACTION} {packageDeactivate}");
            }

            foreach (string packageRemove in PackageRemoves)
            {
                ActionRunner.AddActionToStartup($"{ActionRunner.REMOVE_PACKAGE_ACTION} {packageRemove}");
            }

            foreach (string packageAdd in PackageAdds)
            {
                string package = GetPackage(repos, packageAdd);
                if (package == null)
                {
                    PluginManager.SendLog("Can not Add Package. Url does not exist.");
                    continue;
                }

                ActionRunner.AddActionToStartup($"{ActionRunner.ADD_PACKAGE_ACTION} {package}");
            }

            foreach (string packageAddActivate in PackageAddsActivates)
            {
                string package = GetPackage(repos, packageAddActivate);

                if (package == null)
                {
                    PluginManager.SendLog("Can not Add Package. Url does not exist.");
                    continue;
                }

                ActionRunner.AddActionToStartup($"{ActionRunner.ADD_ACTIVATE_PACKAGE_ACTION} {package}");
            }

            foreach (string packageActivate in PackageActivates)
            {
                ActionRunner.AddActionToStartup($"{ActionRunner.ACTIVATE_PACKAGE_ACTION} {packageActivate}");
            }


            Debug.OnConfigCreate += ProjectDebugConfig_OnConfigCreate;
        }
 public DeactivatePackageEventArgs(BasePluginPointer ptr, bool canCancel) : base(canCancel)
 {
     Pointer = ptr;
 }
Пример #27
0
 /// <summary>
 ///     Installs the Specified folder contents into the Directories of the specified pointer
 /// </summary>
 /// <param name="ptr">The Pointer</param>
 /// <param name="folder">The Folder with contents</param>
 public abstract void Install(BasePluginPointer ptr, string folder);
Пример #28
0
 public void OnPluginLoad(IPlugin plugin, BasePluginPointer ptr)
 {
 }
Пример #29
0
 /// <summary>
 ///     Saves the BasePluginPointer to a Directory
 /// </summary>
 /// <param name="data">Data to Save</param>
 /// <param name="outputFolder">Output Folder</param>
 public abstract void SaveData(BasePluginPointer data, string outputFolder);