Esempio n. 1
0
        /// <inheritdoc />
        public IPluginDescription ReflectPlugin(string pluginPath)
        {
            try
            {
                var archive     = PluginArchive.OpenRead(pluginPath);
                var description = CreateDescription(archive);
                _archivesByPlugin.Add(description, archive);
                return(description);
            }
            catch (Exception e)
            {
                Log.ErrorFormat("Unable to load '{0}': {1}", pluginPath, e);

                string  id;
                Version version;
                ExtractIdAndVersion(pluginPath, out id, out version);
                var description = new PluginDescription
                {
                    Id       = id,
                    Version  = version,
                    Error    = string.Format("The plugin couldn't be loaded: {0}", e.Message),
                    Plugins  = new Dictionary <Type, string>(),
                    FilePath = pluginPath
                };
                _archivesByPlugin.Add(description, new EmptyPluginArchive());
                return(description);
            }
        }
Esempio n. 2
0
        private static IPluginDescription CreateDescription(PluginArchive archive)
        {
            var archiveIndex = archive.Index;

            Uri.TryCreate(archiveIndex.Website, UriKind.Absolute, out var website);

            var plugins = new Dictionary <Type, string>();

            foreach (var pair in archiveIndex.ImplementedPluginInterfaces)
            {
                var pluginInterfaceType = typeof(IPlugin).Assembly.GetType(pair.InterfaceTypename);
                if (pluginInterfaceType != null)
                {
                    plugins.Add(pluginInterfaceType, pair.ImplementationTypename);
                }
                else
                {
                    Log.WarnFormat("Plugin implements unknown interface '{0}', skipping it...", pair.InterfaceTypename);
                }
            }

            var desc = new PluginDescription
            {
                Id          = new PluginId(archiveIndex.Id),
                Name        = archiveIndex.Name,
                Version     = archiveIndex.Version,
                Icon        = LoadIcon(archive.ReadIcon()),
                Author      = archiveIndex.Author,
                Description = archiveIndex.Description,
                Website     = website,
                Plugins     = plugins
            };

            return(desc);
        }
Esempio n. 3
0
        /// <summary>
        ///     Loads the best version of the given plugin.
        /// </summary>
        public void Load()
        {
            Log.DebugFormat("Found {0} version(s) of plugin '{1}', finding compatible ones...", _pluginsByVersion.Count, _id);

            var compatiblePlugins = _pluginsByVersion.Where(x => !(x.Value.Archive is EmptyPluginArchive))
                                    .Where(x => IsCompatible(x.Value.Archive.Index))
                                    .OrderByDescending(x => x.Key)
                                    .Select(x => x.Value).ToList();

            if (compatiblePlugins.Any())
            {
                Log.DebugFormat("Found {0} compatible version(s) of plugin '{1}', loading newest...", _pluginsByVersion.Count, _id);

                // It's possible that despite our best efforts, the plugin with the highest version
                // refuses to be loaded (for example because it's broken, or the compatibility check might miss something).
                // If that's the case, we try to load earlier versions until we either find one that works or
                // give up...
                if (TryLoad(compatiblePlugins, out var loadedPlugin))
                {
                    _selectedPlugin        = CreateDescription(loadedPlugin);
                    _selectedPluginArchive = loadedPlugin.Archive;
                    _status.IsLoaded       = true;
                }
                else
                {
                    _selectedPlugin = new PluginDescription
                    {
                        Id    = _id,
                        Error = "The plugin couldn't be loaded",
                        PluginImplementations = new IPluginImplementationDescription[0]
                    };
                    var plugin = compatiblePlugins.First();                     //< Never empty: we have at least 1 plugin
                    _selectedPlugin.FilePath = plugin.FilePath;
                    _selectedPlugin.Version  = plugin.Archive.Index.Version;

                    _status.IsLoaded = false;
                }
            }
            else
            {
                Log.ErrorFormat("Found 0 compatible version(s) of plugin '{0}' (tried all {1} version(s) of this plugin)", _id, _pluginsByVersion.Count);

                _selectedPlugin = new PluginDescription
                {
                    Id    = _id,
                    Error = "The plugin couldn\'t be loaded",
                    PluginImplementations = new IPluginImplementationDescription[0]
                };

                if (_pluginsByVersion.Any())                 //< Might be empty
                {
                    var plugin = _pluginsByVersion.Values.First();
                    _selectedPlugin.FilePath = plugin.FilePath;
                    _selectedPlugin.Version  = plugin.Archive.Index.Version;
                }

                _status.IsLoaded = false;
            }
        }
Esempio n. 4
0
        private static PluginDescription CreateDescription(Plugin plugin)
        {
            var archive      = plugin.Archive;
            var archiveIndex = plugin.Archive.Index;

            Uri.TryCreate(archiveIndex.Website, UriKind.Absolute, out var website);

            var plugins = new List <IPluginImplementationDescription>();

            foreach (var description in archiveIndex.ImplementedPluginInterfaces)
            {
                var pluginInterfaceType = ResolvePluginInterface(description);
                if (pluginInterfaceType != null)
                {
                    plugins.Add(new PluginImplementationDescription(description)
                    {
                        InterfaceType = pluginInterfaceType
                    });
                }
                else
                {
                    Log.WarnFormat("Plugin implements unknown interface '{0}', skipping it...",
                                   description.InterfaceTypename);
                }
            }

            var serializableTypes = new Dictionary <string, string>();

            foreach (var pair in archiveIndex.SerializableTypes)
            {
                serializableTypes.Add(pair.Name, pair.FullName);
            }

            var changes = new List <Change>();

            foreach (var serializableChange in archive.LoadChanges())
            {
                changes.Add(new Change(serializableChange));
            }

            var desc = new PluginDescription
            {
                Id                    = new PluginId(archiveIndex.Id),
                Name                  = archiveIndex.Name,
                Version               = archiveIndex.Version,
                Icon                  = LoadIcon(plugin.Archive.ReadIcon()),
                FilePath              = plugin.FilePath,
                Author                = archiveIndex.Author,
                Description           = archiveIndex.Description,
                Website               = website,
                PluginImplementations = plugins,
                SerializableTypes     = serializableTypes,
                Changes               = changes,
                TailviewerApiVersion  = archiveIndex.TailviewerApiVersion
            };

            return(desc);
        }
Esempio n. 5
0
 private bool TryLoad(string filePath, out IPluginDescription description)
 {
     try
     {
         description = ReflectPlugin(filePath);
         return(true);
     }
     catch (FileLoadException e)
     {
         var error = string.Format("Unable to load plugin '{0}': {1}", filePath, e);
         Log.Error(error);
         description = new PluginDescription
         {
             FilePath = filePath,
             Error    = error
         };
         return(false);
     }
     catch (BadImageFormatException e)
     {
         var error = string.Format("Unable to load plugin '{0}' (plugins must be compiled against AnyCPU): {1}", filePath,
                                   e);
         Log.Error(error);
         description = new PluginDescription
         {
             FilePath = filePath,
             Error    = error
         };
         return(false);
     }
     catch (Exception e)
     {
         var error = string.Format("Caught unexpected exception while trying to load plugin '{0}': {1}",
                                   filePath, e);
         Log.Error(error);
         description = new PluginDescription
         {
             FilePath = filePath,
             Error    = error
         };
         return(false);
     }
 }