public void DeduplicateExtListTest()
        {
            var manifests = new List <BaseExtensionManifest>
            {
                new ExtensionManifest {
                    Id = "test1", Version = "1.0"
                },
                new ExtensionManifest {
                    Id = "test1", Version = "3.0"
                },
                new ExtensionManifest {
                    Id = "test1", Version = "2.0.2"
                },
                new ExtensionManifest {
                    Id = "test2", Version = "5.0.1.2"
                },
                new ExtensionManifest {
                    Id = "test3", Version = "1.0"
                },
                new ExtensionManifest {
                    Id = "test3", Version = "1.0.1"
                },
            };

            var list = ExtensionFactory.DeduplicateExtList(manifests).ToList();

            Assert.AreEqual(3, list.Count);
            Assert.AreEqual("3.0", list[0].Version);
            Assert.AreEqual("5.0.1.2", list[1].Version);
            Assert.AreEqual("1.0.1", list[2].Version);
        }
Beispiel #2
0
        public static string PackageExtension(string extDirectory, string targetPath)
        {
            var dirInfo    = new DirectoryInfo(extDirectory);
            var extInfo    = ExtensionFactory.GetDescriptionFromFile(Path.Combine(extDirectory, PlaynitePaths.ExtensionManifestFileName));
            var packedPath = Path.Combine(targetPath, $"{dirInfo.Name}_{extInfo.Version.ToString().Replace(".", "_")}{PlaynitePaths.PackedExtensionFileExtention}");

            FileSystem.PrepareSaveFile(packedPath);
            var ignoreFiles = File.ReadAllLines(Paths.ExtFileIgnoreListPath);

            using (var zipStream = new FileStream(packedPath, FileMode.Create))
            {
                using (var zipFile = new ZipArchive(zipStream, ZipArchiveMode.Create))
                {
                    foreach (var file in Directory.GetFiles(extDirectory, "*.*", SearchOption.AllDirectories))
                    {
                        var subName = file.Replace(extDirectory, "").TrimStart(Path.DirectorySeparatorChar);
                        if (ignoreFiles.ContainsString(subName, StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }

                        zipFile.CreateEntryFromFile(file, subName);
                    }
                }
            }

            return(packedPath);
        }
        public static UserControl GetPluginSettingsView(Guid pluginId, ExtensionFactory extensions, Dictionary <Guid, PluginSettingsItem> loadedPluginSettings)
        {
            if (loadedPluginSettings.TryGetValue(pluginId, out var settings))
            {
                return(settings.View);
            }

            try
            {
                var plugin      = extensions.Plugins.Values.First(a => a.Plugin.Id == pluginId);
                var provSetting = plugin.Plugin.GetSettings(false);
                var provView    = plugin.Plugin.GetSettingsView(false);
                if (provSetting != null && provView != null)
                {
                    provView.DataContext = provSetting;
                    provSetting.BeginEdit();
                    var plugSetting = new PluginSettingsItem()
                    {
                        Name     = plugin.Description.Name,
                        Settings = provSetting,
                        View     = provView
                    };

                    loadedPluginSettings.Add(pluginId, plugSetting);
                    return(provView);
                }
            }
            catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
            {
                logger.Error(e, $"Failed to load plugin settings, {pluginId}");
                return(new Controls.SettingsSections.ErrorLoading());
            }

            return(new Controls.SettingsSections.NoSettingsAvailable());
        }
Beispiel #4
0
 public PlayniteAPI(
     IGameDatabaseAPI databaseApi,
     IDialogsFactory dialogs,
     IMainViewAPI mainViewApi,
     IPlayniteInfoAPI infoApi,
     IPlaynitePathsAPI pathsApi,
     IWebViewFactory webViewFactory,
     IResourceProvider resources,
     INotificationsAPI notifications,
     GamesEditor gameEditor,
     IUriHandlerAPI uriHandler,
     IPlayniteSettingsAPI settingsApi,
     IAddons addonsApi,
     IEmulationAPI emulation,
     ExtensionFactory extensions)
 {
     WebViews            = webViewFactory;
     Paths               = pathsApi;
     ApplicationInfo     = infoApi;
     MainView            = mainViewApi;
     Dialogs             = dialogs;
     Database            = databaseApi;
     Resources           = resources;
     Notifications       = notifications;
     this.gameEditor     = gameEditor;
     UriHandler          = uriHandler;
     ApplicationSettings = settingsApi;
     Addons              = addonsApi;
     Emulation           = emulation;
     this.extensions     = extensions;
     SDK.API.Instance    = this;
 }
Beispiel #5
0
        public static ExceptionInfo GetExceptionInfo(Exception exception, ExtensionFactory extensions)
        {
            try
            {
                var stack        = new StackTrace(exception);
                var crashModules = new List <string>();
                foreach (var frame in stack.GetFrames())
                {
                    crashModules.AddMissing(frame.GetMethod().Module.Name);
                }

                var extDesc = extensions.Plugins.FirstOrDefault(a => crashModules.ContainsString(a.Value.Description.Module, StringComparison.OrdinalIgnoreCase)).Value;
                if (extDesc != null)
                {
                    return(new ExceptionInfo
                    {
                        IsExtensionCrash = true,
                        CrashExtension = extDesc.Description
                    });
                }
                else
                {
                    return(new ExceptionInfo());
                }
            }
            catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
            {
                logger.Error(e, "Failed check crash stack trace.");
                return(new ExceptionInfo());
            }
        }
Beispiel #6
0
        public static void InitializePluginControls(
            ExtensionFactory extensions,
            ControlTemplate template,
            FrameworkElement templateParent,
            ApplicationMode mode,
            object contextSource,
            string contextPath)
        {
            if (DesignerTools.IsInDesignMode)
            {
                return;
            }

            foreach (var p in extensions.CustomElementList)
            {
                foreach (var elemName in p.ElementList)
                {
                    if (template.FindName($"{p.SourceName}_{elemName}", templateParent) is ContentControl elem)
                    {
                        Control plugControl = null;
                        try
                        {
                            plugControl = p.Source.GetGameViewControl(new SDK.Plugins.GetGameViewControlArgs
                            {
                                Name = elemName,
                                Mode = mode
                            });
                        }
                        catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                        {
                            logger.Error(e, $"Failed to get plugin control: {p.Source}.");
                        }

                        if (plugControl == null)
                        {
                            continue;
                        }

                        if (contextSource == null)
                        {
                            BindingTools.SetBinding(plugControl,
                                                    plugControl is PluginUserControl ? PluginUserControl.GameContextProperty : Control.DataContextProperty,
                                                    contextPath);
                        }
                        else
                        {
                            BindingTools.SetBinding(plugControl,
                                                    plugControl is PluginUserControl ? PluginUserControl.GameContextProperty : Control.DataContextProperty,
                                                    contextSource,
                                                    contextPath);
                        }

                        elem.Focusable = false;
                        elem.Content   = plugControl;
                    }
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Loads extenstions.
        /// </summary>
        private void LoadExtensions()
        {
            ExtensionHolder = new(ErrLog);

            foreach (string extensionCode in AppConfig.ExtensionCodes)
            {
                if (ExtensionFactory.GetExtensionLogic(AppDirs.LibDir, extensionCode, this,
                                                       out ExtensionLogic extensionLogic, out string message))
                {
                    ExtensionHolder.AddExtension(extensionLogic);
                }
Beispiel #8
0
        public void Instantiate_ExtendArgsNCalc_NCalcExtendEngine()
        {
            var factory  = new ExtensionFactory(null, new Context(null));
            var extender = factory.Instantiate(new ExtendArgs(
                                                   new ColumnOrdinalIdentifier(1),
                                                   "a+b*c",
                                                   LanguageType.NCalc
                                                   ));

            Assert.That(extender, Is.Not.Null);
            Assert.That(extender, Is.TypeOf <NCalcExtendEngine>());
        }
Beispiel #9
0
        public void Instantiate_ExtendArgsNative_NativeExtendEngine()
        {
            var factory  = new ExtensionFactory(null, new Context(null));
            var extender = factory.Instantiate(new ExtendArgs(
                                                   new ColumnOrdinalIdentifier(1),
                                                   "[A] | dateTime-to-date | dateTime-to-add(00:15:00, [B])",
                                                   LanguageType.Native
                                                   ));

            Assert.That(extender, Is.Not.Null);
            Assert.That(extender, Is.TypeOf <NativeExtendEngine>());
        }
        public void LoadPluginsTest()
        {
            var api     = new Mock <IPlayniteAPI>();
            var factory = new ExtensionFactory(new GameDatabase(), new GameControllerFactory());

            var descriptors = factory.GetExtensionDescriptors();

            Assert.AreEqual(2, descriptors.Count);

            factory.LoadPlugins(api.Object, null, false);
            Assert.AreEqual(2, factory.Plugins.Count);
        }
Beispiel #11
0
 public DesktopGamesEditor(
     GameDatabase database,
     GameControllerFactory controllerFactory,
     PlayniteSettings appSettings,
     IDialogsFactory dialogs,
     ExtensionFactory extensions,
     PlayniteApplication app) : base(
         database,
         controllerFactory,
         appSettings,
         dialogs,
         extensions,
         app)
 {
 }
Beispiel #12
0
 public FullscreenCollectionView(
     IGameDatabase database,
     PlayniteSettings settings,
     ExtensionFactory extensions) : base(database, extensions, settings.Fullscreen.FilterSettings)
 {
     this.settings = settings;
     Database.Games.ItemCollectionChanged += Database_GamesCollectionChanged;
     Database.Games.ItemUpdated           += Database_GameUpdated;
     viewSettings = settings.Fullscreen.ViewSettings;
     viewSettings.PropertyChanged += ViewSettings_PropertyChanged;
     using (CollectionView.DeferRefresh())
     {
         SetViewDescriptions();
         Items.AddRange(Database.Games.Select(x => new GamesCollectionViewEntry(x, GetLibraryPlugin(x), settings)));
     };
 }
        public IGameController GetGameBasedController(Game game, ExtensionFactory extensions)
        {
            if (game.IsCustomGame)
            {
                return(new GenericGameController(database, game));
            }
            else
            {
                if (extensions.Plugins.TryGetValue(game.PluginId, out var plugin))
                {
                    return(((LibraryPlugin)plugin.Plugin).GetGameController(game.GetClone()) ?? new GenericGameController(database, game));
                }
            }

            logger.Error($"Unable to find controller responsible for {game.Name} game.");
            return(null);
        }
Beispiel #14
0
 public GamesEditor(
     GameDatabase database,
     GameControllerFactory controllerFactory,
     PlayniteSettings appSettings,
     IDialogsFactory dialogs,
     ExtensionFactory extensions)
 {
     this.dialogs             = dialogs;
     this.database            = database;
     this.appSettings         = appSettings;
     this.extensions          = extensions;
     controllers              = controllerFactory;
     controllers.Installed   += Controllers_Installed;
     controllers.Uninstalled += Controllers_Uninstalled;
     controllers.Started     += Controllers_Started;
     controllers.Stopped     += Controllers_Stopped;
 }
Beispiel #15
0
        /// <summary>
        /// Initializes the extension item if needed.
        /// </summary>
        private void InitExtensionItem(ExtentionItem extensionItem)
        {
            if (!extensionItem.IsInitialized)
            {
                extensionItem.IsInitialized = true;

                if (ExtensionFactory.GetExtensionLogic(appData.AppDirs.LibDir, extensionItem.ExtentionCode, appData,
                                                       out ExtensionLogic extensionLogic, out string message))
                {
                    extensionItem.Descr          = BuildExtensionDescr(extensionLogic);
                    extensionItem.ExtensionLogic = extensionLogic;
                }
                else
                {
                    extensionItem.Descr          = message;
                    extensionItem.ExtensionLogic = null;
                }
            }
Beispiel #16
0
 public GamesEditor(
     GameDatabase database,
     GameControllerFactory controllerFactory,
     PlayniteSettings appSettings,
     IDialogsFactory dialogs,
     ExtensionFactory extensions,
     PlayniteApplication app)
 {
     this.Dialogs                 = dialogs;
     this.Database                = database;
     this.AppSettings             = appSettings;
     this.Extensions              = extensions;
     this.Application             = app;
     controllers                  = controllerFactory;
     controllers.Installed       += Controllers_Installed;
     controllers.Uninstalled     += Controllers_Uninstalled;
     controllers.Started         += Controllers_Started;
     controllers.Stopped         += Controllers_Stopped;
     AppSettings.PropertyChanged += AppSettings_PropertyChanged;
 }
        public void LoadGenericPluginTest()
        {
            var api     = new Mock <IPlayniteAPI>();
            var factory = new ExtensionFactory(new GameDatabase(), new GameControllerFactory());

            var descriptors = factory.GetExtensionDescriptors();

            Assert.AreEqual(2, descriptors.Count);

            var descriptor = descriptors[0];

            factory.LoadGenericPlugins(api.Object, null);
            Assert.AreEqual(1, factory.GenericPlugins.Count);
            Assert.AreEqual(0, factory.LibraryPlugins.Count);

            factory.LoadGenericPlugins(api.Object, new List <string>()
            {
                "TestPlugin"
            });
            Assert.AreEqual(0, factory.GenericPlugins.Count);
        }
Beispiel #18
0
        public DesignMainViewModel()
        {
            ProgressStatus  = "Status example in progress...";
            ProgressValue   = 50;
            ProgressTotal   = 100;
            ProgressVisible = true;

            var database = new InMemoryGameDatabase();

            Game.DatabaseReference = database;
            GameDatabase.GenerateSampleData(database);
            var designGame = database.Games.First();

            designGame.CoverImage      = "pack://application:,,,/Playnite;component/Resources/Images/DesignCover.jpg";
            designGame.BackgroundImage = "pack://application:,,,/Playnite;component/Resources/Images/DesignBackground.jpg";
            designGame.Icon            = "pack://application:,,,/Playnite;component/Resources/Images/DesignIcon.png";

            AppSettings = new PlayniteSettings();
            AppSettings.ExplorerPanelVisible               = true;
            AppSettings.GridViewSideBarVisible             = true;
            AppSettings.ShowNamesUnderCovers               = true;
            AppSettings.ShowNameEmptyCover                 = true;
            AppSettings.ViewSettings.SelectedExplorerField = GroupableField.LastActivity;

            Extensions = new ExtensionFactory(database, new GameControllerFactory());
            GamesView  = new DesktopCollectionView(database, AppSettings, Extensions);

            SelectedGame  = GamesView.Items[0];
            SelectedGames = new List <GamesCollectionViewEntry>()
            {
                SelectedGame
            };
            SelectedGameDetails = new GameDetailsViewModel(GamesView.Items[0], AppSettings);
            DatabaseExplorer    = new DatabaseExplorer(database, Extensions, AppSettings);

            PlayniteApi = new PlayniteAPI(null, null, null, null, null, null, null, new NotificationsAPI(), null, null);
            PlayniteApi.Notifications.Add(new NotificationMessage("1", "Some testing notification message.", NotificationType.Info));
            PlayniteApi.Notifications.Add(new NotificationMessage("2", "Some really long testing notification message that should be on more lines of text.", NotificationType.Error));
        }
Beispiel #19
0
        public static ItemType GetExtensionType(string directory)
        {
            var themeMan = Path.Combine(directory, PlaynitePaths.ThemeManifestFileName);
            var extMan   = Path.Combine(directory, PlaynitePaths.ExtensionManifestFileName);

            if (File.Exists(themeMan))
            {
                var desc = ThemeManager.GetDescriptionFromFile(themeMan);
                switch (desc.Mode)
                {
                case ApplicationMode.Desktop:
                    return(ItemType.DesktopTheme);

                case ApplicationMode.Fullscreen:
                    return(ItemType.FullscreenTheme);
                }
            }
            else if (File.Exists(extMan))
            {
                var desc = ExtensionFactory.GetDescriptionFromFile(extMan);
                switch (desc.Type)
                {
                case ExtensionType.GenericPlugin:
                    return(ItemType.GenericPlugin);

                case ExtensionType.GameLibrary:
                    return(ItemType.LibraryPlugin);

                case ExtensionType.Script:
                    return(desc.Module.EndsWith("ps1", StringComparison.OrdinalIgnoreCase) ? ItemType.PowerShellScript : ItemType.IronPythonScript);

                case ExtensionType.MetadataProvider:
                    return(ItemType.MetadataPlugin);
                }
            }

            return(ItemType.Uknown);
        }
Beispiel #20
0
 public void Initialize()
 {
     _factory = Container.GetExportedValue <ExtensionFactory>();
     _factory.InitializeCaptureDevices(this);
     _factory.SyncEnabledCaptureDevices();
 }
Beispiel #21
0
 public void Initialize()
 {
     _factory = Container.GetExportedValue <ExtensionFactory>();
 }
Beispiel #22
0
 public AddonsAPI(ExtensionFactory extensions, PlayniteSettings settings)
 {
     this.extensions = extensions;
     this.settings   = settings;
 }
Beispiel #23
0
        public static ExceptionInfo GetExceptionInfo(Exception exception, ExtensionFactory extensions)
        {
            try
            {
                var playniteStackCalls = 0;
                var stack        = new StackTrace(exception);
                var crashModules = new List <Module>();
                foreach (var frame in stack.GetFrames())
                {
                    var module = frame.GetMethod().Module;
                    if (module.Name.StartsWith("Playnite"))
                    {
                        playniteStackCalls++;
                    }

                    crashModules.AddMissing(module);
                }

                if (exception.InnerException != null)
                {
                    stack = new StackTrace(exception.InnerException);
                    foreach (var frame in stack.GetFrames())
                    {
                        var module = frame.GetMethod().Module;
                        if (module.Name.StartsWith("Playnite"))
                        {
                            playniteStackCalls++;
                        }

                        crashModules.AddMissing(module);
                    }
                }

                var extDesc = extensions?.Plugins?.FirstOrDefault(a =>
                                                                  crashModules.FirstOrDefault(m => m.Name ==
                                                                                              a.Value.Description.Module ||
                                                                                              Paths.AreEqual(a.Value.Description.DirectoryPath, Path.GetDirectoryName(m.Assembly.Location))) != null).Value;
                if (extDesc != null)
                {
                    return(new ExceptionInfo
                    {
                        IsExtensionCrash = true,
                        CrashExtension = extDesc.Description
                    });
                }
                else
                {
                    // This usually happens if an exception occurs in XAML because of faulty custom theme.
                    // The only stack entry would be Playnite's entry point or no entry at all.
                    if (playniteStackCalls == 0 || playniteStackCalls == 1)
                    {
                        return(new ExceptionInfo {
                            IsExtensionCrash = true
                        });
                    }
                    else
                    {
                        return(new ExceptionInfo());
                    }
                }
            }
            catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
            {
                logger.Error(e, "Failed check crash stack trace.");
                return(new ExceptionInfo());
            }
        }
Beispiel #24
0
        public static List <ThemeManifest> GetAvailableThemes(ApplicationMode mode)
        {
            var modeDir = GetThemeRootDir(mode);
            var user    = new List <BaseExtensionManifest>();
            var install = new List <BaseExtensionManifest>();

            var userPath = Path.Combine(PlaynitePaths.ThemesUserDataPath, modeDir);

            if (!PlayniteSettings.IsPortable && Directory.Exists(userPath))
            {
                foreach (var dir in Directory.GetDirectories(userPath))
                {
                    try
                    {
                        var descriptorPath = Path.Combine(dir, PlaynitePaths.ThemeManifestFileName);
                        if (File.Exists(descriptorPath))
                        {
                            var info = new FileInfo(descriptorPath);
                            var man  = new ThemeManifest(descriptorPath);
                            if (!man.Id.IsNullOrEmpty())
                            {
                                user.Add(man);
                            }
                        }
                    }
                    catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                    {
                        logger.Error(e, $"Failed to load theme info {dir}");
                    }
                }
            }

            var programPath = Path.Combine(PlaynitePaths.ThemesProgramPath, modeDir);

            if (Directory.Exists(programPath))
            {
                foreach (var dir in Directory.GetDirectories(programPath))
                {
                    try
                    {
                        var descriptorPath = Path.Combine(dir, PlaynitePaths.ThemeManifestFileName);
                        if (File.Exists(descriptorPath))
                        {
                            var info = new FileInfo(descriptorPath);
                            var man  = new ThemeManifest(descriptorPath);
                            if (!man.Id.IsNullOrEmpty())
                            {
                                if (user.Any(a => a.Id == man.Id))
                                {
                                    continue;
                                }
                                else
                                {
                                    install.Add(man);
                                }
                            }
                        }
                    }
                    catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                    {
                        logger.Error(e, $"Failed to load theme info {dir}");
                    }
                }
            }

            var result = new List <ThemeManifest>();

            result.AddRange(ExtensionFactory.DeduplicateExtList(user).Cast <ThemeManifest>());
            result.AddRange(ExtensionFactory.DeduplicateExtList(install).Cast <ThemeManifest>());
            return(result);
        }