@@ -26,30 +26,31 @@ namespace NVIDIAGeForceNowEnabler
2626{
2727 public class NVIDIAGeForceNowEnabler : LibraryPlugin
2828 {
29- private static readonly ILogger logger = LogManager . GetLogger ( ) ;
30- private readonly string geforceNowWorkingPath ;
31- public readonly string geforceNowExecutablePath ;
32- private readonly string gfnDatabasePath ;
33- private Dictionary < Guid , AppStore > pluginIdToAppStoreMapper ;
34- private readonly HashSet < AppStore > appStoresToMatchByName ;
35- private bool databaseUpdatedOnGetGames = false ;
36- private Dictionary < Tuple < AppStore , string > , GeforceNowItemVariant > detectionDictionary = new Dictionary < Tuple < AppStore , string > , GeforceNowItemVariant > ( ) ;
37-
38- private NVIDIAGeForceNowEnablerSettingsViewModel settings { get ; set ; }
29+ private static readonly ILogger _logger = LogManager . GetLogger ( ) ;
30+
31+ private readonly string _geforceNowWorkingPath ;
32+ private readonly string _gfnDatabasePath ;
33+ public readonly string _geforceNowExecutablePath ;
34+
35+ private readonly NVIDIAGeForceNowEnablerSettingsViewModel _settings ;
36+ private readonly HashSet < AppStore > _appStoresToMatchByName ;
37+
38+ private Dictionary < Guid , AppStore > _pluginIdToAppStoreMapper ;
39+ private Dictionary < Tuple < AppStore , string > , GeforceNowItemVariant > _detectionDictionary = new Dictionary < Tuple < AppStore , string > , GeforceNowItemVariant > ( ) ;
40+
41+ private bool _databaseUpdatedOnGetGames = false ;
42+
3943 public override LibraryClient Client { get ; } = new NVIDIAGeForceNowClient ( ) ;
4044 public override Guid Id { get ; } = Guid . Parse ( "5f2dfd12-5f13-46fe-bcdd-64eb53ace26a" ) ;
4145 public override string Name => "NVIDIA GeForce NOW" ;
4246 public override string LibraryIcon { get ; }
47+
4348 public NVIDIAGeForceNowEnabler ( IPlayniteAPI api ) : base ( api )
4449 {
45- settings = new NVIDIAGeForceNowEnablerSettingsViewModel ( this ) ;
46- geforceNowWorkingPath = Path . Combine ( Environment . GetEnvironmentVariable ( "LocalAppData" ) , "NVIDIA Corporation" , "GeForceNOW" , "CEF" ) ;
47- geforceNowExecutablePath = Path . Combine ( geforceNowWorkingPath , "GeForceNOWStreamer.exe" ) ;
48- gfnDatabasePath = Path . Combine ( GetPluginUserDataPath ( ) , "gfnDatabase.json" ) ;
49- Properties = new LibraryPluginProperties
50- {
51- HasSettings = true
52- } ;
50+ _settings = new NVIDIAGeForceNowEnablerSettingsViewModel ( this ) ;
51+ _geforceNowWorkingPath = Path . Combine ( Environment . GetEnvironmentVariable ( "LocalAppData" ) , "NVIDIA Corporation" , "GeForceNOW" , "CEF" ) ;
52+ _geforceNowExecutablePath = Path . Combine ( _geforceNowWorkingPath , "GeForceNOWStreamer.exe" ) ;
53+ _gfnDatabasePath = Path . Combine ( GetPluginUserDataPath ( ) , "gfnDatabase.json" ) ;
5354
5455 // For some libraries, game names need to be used because the GameId provided by plugins
5556 // don't match with the StoreId used in the GeForce Now database
@@ -60,21 +61,14 @@ public NVIDIAGeForceNowEnabler(IPlayniteAPI api) : base(api)
6061
6162 // For Epic they don't share any similarity and remains to be investigated. Examples:
6263 // Epic: Pillars of Eternity - Definitive Edition, GameId: bcc75c246fe04e45b0c1f1c3fd52503a, StoreId: bc31288122a7443b818f4e77eed5ce25
63- appStoresToMatchByName = new HashSet < AppStore >
64+ _appStoresToMatchByName = new HashSet < AppStore >
6465 {
6566 AppStore . Epic ,
6667 AppStore . EA_APP ,
6768 AppStore . Xbox
6869 } ;
6970
70- LibraryIcon = Path . Combine ( Path . GetDirectoryName ( Assembly . GetExecutingAssembly ( ) . Location ) , @"icon.png" ) ;
71- SetEnumsDictionary ( ) ;
72- LoadDatabaseFromFile ( ) ;
73- }
74-
75- private void SetEnumsDictionary ( )
76- {
77- pluginIdToAppStoreMapper = new Dictionary < Guid , AppStore >
71+ _pluginIdToAppStoreMapper = new Dictionary < Guid , AppStore >
7872 {
7973 [ Guid . Parse ( "e3c26a3d-d695-4cb7-a769-5ff7612c7edd" ) ] = AppStore . Battlenet ,
8074 [ Guid . Parse ( "0e2e793e-e0dd-4447-835c-c44a1fd506ec" ) ] = AppStore . Bethesda ,
@@ -94,53 +88,73 @@ private void SetEnumsDictionary()
9488 [ Guid . Parse ( "7e4fbb5e-2ae3-48d4-8ba0-6b30e7a4e287" ) ] = AppStore . Xbox
9589 //[Guid.Parse("99999999-9999-9999-9999-999999999999")] = AppStore.Wargaming
9690 } ;
91+
92+ LibraryIcon = Path . Combine ( Path . GetDirectoryName ( Assembly . GetExecutingAssembly ( ) . Location ) , @"icon.png" ) ;
93+
94+ var cachedDatabase = LoadDatabaseFromFile ( _gfnDatabasePath ) ;
95+ SetDetectionDictionary ( cachedDatabase ) ;
96+
97+ Properties = new LibraryPluginProperties
98+ {
99+ HasSettings = true
100+ } ;
97101 }
98102
99- private void LoadDatabaseFromFile ( )
103+ private static List < GeforceNowItem > LoadDatabaseFromFile ( string filePath )
100104 {
101- if ( ! FileSystem . FileExists ( gfnDatabasePath ) )
105+ if ( ! FileSystem . FileExists ( filePath ) )
102106 {
103- logger . Debug ( $ "Database in { gfnDatabasePath } not found on startup ") ;
104- return ;
107+ _logger . Debug ( $ "File not found at path ' { filePath } '. Returning an empty list. ") ;
108+ return new List < GeforceNowItem > ( ) ;
105109 }
106110
107- var supportedList = Serialization . FromJsonFile < List < GeforceNowItem > > ( gfnDatabasePath ) ;
108- logger . Debug ( $ "Deserialized database in { gfnDatabasePath } with { supportedList . Count } entries on startup") ;
109- SetDetectionDictionary ( supportedList ) ;
111+ try
112+ {
113+ _logger . Debug ( $ "Loading data from file at '{ filePath } '.") ;
114+ return Serialization . FromJsonFile < List < GeforceNowItem > > ( filePath ) ;
115+ }
116+ catch ( Exception e )
117+ {
118+ _logger . Error ( e , $ "Failed to deserialize file at '{ filePath } '. File will be deleted.") ;
119+ FileSystem . DeleteFileSafe ( filePath ) ;
120+ }
121+
122+ return new List < GeforceNowItem > ( ) ;
110123 }
111124
125+
112126 public override void OnApplicationStarted ( OnApplicationStartedEventArgs args )
113127 {
114- if ( settings . Settings . ExecuteOnStartup )
128+ if ( _settings . Settings . ExecuteOnStartup )
115129 {
116130 UpdateDatabaseAndGamesStatus ( false ) ;
117131 }
118132 }
119133
120134 public override void OnLibraryUpdated ( OnLibraryUpdatedEventArgs args )
121135 {
122- if ( settings . Settings . ExecuteOnLibraryUpdate )
136+ if ( _settings . Settings . ExecuteOnLibraryUpdate )
123137 {
124- var updateDatabase = ! databaseUpdatedOnGetGames ;
138+ var updateDatabase = ! _databaseUpdatedOnGetGames ;
125139 UpdateDatabaseAndGamesStatus ( false , ! updateDatabase ) ;
126140 }
127141
128- databaseUpdatedOnGetGames = false ;
142+ _databaseUpdatedOnGetGames = false ;
129143 }
130144
131145 public override IEnumerable < GameMetadata > GetGames ( LibraryGetGamesArgs args )
132146 {
133147 // To prevent downloading the database again during OnLibraryUpdated event
134- databaseUpdatedOnGetGames = false ;
148+ _databaseUpdatedOnGetGames = false ;
135149 var games = new List < GameMetadata > ( ) ;
136- if ( ! settings . Settings . ImportDatabaseAsLibrary )
150+ if ( ! _settings . Settings . ImportDatabaseAsLibrary )
137151 {
138152
139153 return games ;
140154 }
141155
142- databaseUpdatedOnGetGames = DownloadAndRefreshGameList ( false ) ;
143- if ( ! detectionDictionary . HasItems ( ) )
156+ _databaseUpdatedOnGetGames = DownloadAndRefreshGameList ( false ) ;
157+ if ( ! _detectionDictionary . HasItems ( ) )
144158 {
145159 return games ;
146160 }
@@ -170,7 +184,7 @@ public override IEnumerable<GameMetadata> GetGames(LibraryGetGamesArgs args)
170184
171185 public override ISettings GetSettings ( bool firstRunSettings )
172186 {
173- return settings ;
187+ return _settings ;
174188 }
175189
176190 public override UserControl GetSettingsView ( bool firstRunSettings )
@@ -215,7 +229,7 @@ private void OpenEditorWindow()
215229 window . Title = ResourceProvider . GetString ( "LOCNgfn_Enabler_DatabaseBrowserWindowTitle" ) ;
216230
217231 window . Content = new GfnDatabaseBrowserView ( ) ;
218- window . DataContext = new GfnDatabaseBrowserViewModel ( PlayniteApi , detectionDictionary . Select ( x => x . Value ) . ToList ( ) ) ;
232+ window . DataContext = new GfnDatabaseBrowserViewModel ( PlayniteApi , _detectionDictionary . Select ( x => x . Value ) . ToList ( ) ) ;
219233 window . Owner = PlayniteApi . Dialogs . GetCurrentAppWindow ( ) ;
220234 window . WindowStartupLocation = WindowStartupLocation . CenterScreen ;
221235
@@ -232,14 +246,14 @@ public bool DownloadAndRefreshGameList(bool showDialogs)
232246 var downloadedDatabase = GeforceNowService . GetGeforceNowDatabase ( ) ;
233247 if ( downloadedDatabase . Count > 0 )
234248 {
235- FileSystem . WriteStringToFile ( gfnDatabasePath , Serialization . ToJson ( downloadedDatabase ) ) ;
249+ FileSystem . WriteStringToFile ( _gfnDatabasePath , Serialization . ToJson ( downloadedDatabase ) , true ) ;
236250 SetDetectionDictionary ( downloadedDatabase ) ;
237251 databaseUpdated = true ;
238252 }
239253 }
240254 catch ( Exception e )
241255 {
242- logger . Error ( e , $ "Error downloading database.") ;
256+ _logger . Error ( e , $ "Error downloading database.") ;
243257 if ( showDialogs )
244258 {
245259 PlayniteApi . Dialogs . ShowErrorMessage ( e . Message , "NVIDIA GeForce NOW Enabler" ) ;
@@ -252,7 +266,7 @@ public bool DownloadAndRefreshGameList(bool showDialogs)
252266
253267 private void SetDetectionDictionary ( List < GeforceNowItem > geforceList )
254268 {
255- detectionDictionary = new Dictionary < Tuple < AppStore , string > , GeforceNowItemVariant > ( ) ;
269+ _detectionDictionary = new Dictionary < Tuple < AppStore , string > , GeforceNowItemVariant > ( ) ;
256270 foreach ( var geforceNowItem in geforceList )
257271 {
258272 if ( geforceNowItem . Type != AppType . Game )
@@ -267,15 +281,15 @@ private void SetDetectionDictionary(List<GeforceNowItem> geforceList)
267281 continue ;
268282 }
269283
270- if ( appStoresToMatchByName . Contains ( itemVariant . AppStore ) )
284+ if ( _appStoresToMatchByName . Contains ( itemVariant . AppStore ) )
271285 {
272286 var key = Tuple . Create ( itemVariant . AppStore , SatinizeGameName ( itemVariant . Title ) ) ;
273- detectionDictionary [ key ] = itemVariant ;
287+ _detectionDictionary [ key ] = itemVariant ;
274288 }
275289 else
276290 {
277291 var key = Tuple . Create ( itemVariant . AppStore , itemVariant . StoreId ) ;
278- detectionDictionary [ key ] = itemVariant ;
292+ _detectionDictionary [ key ] = itemVariant ;
279293 }
280294 }
281295 }
@@ -302,11 +316,11 @@ public void UpdateDatabaseAndGamesStatus(bool showDialogs, bool updateDatabase =
302316 {
303317 DownloadAndRefreshGameList ( showDialogs ) ;
304318 }
305- if ( ! detectionDictionary . HasItems ( ) )
319+ if ( ! _detectionDictionary . HasItems ( ) )
306320 {
307321 // In case download failed.
308322 // Also sometimes there are issues with the api and it doesn't return any games in the response
309- logger . Debug ( $ "Supported games were 0 so execution was stopped") ;
323+ _logger . Debug ( $ "Supported games were 0 so execution was stopped") ;
310324 return ;
311325 }
312326
@@ -326,7 +340,7 @@ public void UpdateDatabaseAndGamesStatus(bool showDialogs, bool updateDatabase =
326340 if ( PlayniteUtilities . RemoveFeatureFromGame ( PlayniteApi , game , feature ) )
327341 {
328342 featureRemovedCount ++ ;
329- logger . Info ( string . Format ( "Feature removed from \" {0}\" " , game . Name ) ) ;
343+ _logger . Info ( string . Format ( "Feature removed from \" {0}\" " , game . Name ) ) ;
330344 }
331345 }
332346 else
@@ -335,26 +349,26 @@ public void UpdateDatabaseAndGamesStatus(bool showDialogs, bool updateDatabase =
335349 if ( PlayniteUtilities . AddFeatureToGame ( PlayniteApi , game , feature ) )
336350 {
337351 featureAddedCount ++ ;
338- logger . Info ( string . Format ( "Feature added to \" {0}\" " , game . Name ) ) ;
352+ _logger . Info ( string . Format ( "Feature added to \" {0}\" " , game . Name ) ) ;
339353 }
340354
341- if ( settings . Settings . ShowPlayActionsOnLaunch && ! game . IsInstalled )
355+ if ( _settings . Settings . ShowPlayActionsOnLaunch && ! game . IsInstalled )
342356 {
343357 game . IsInstalled = true ;
344358 setAsInstalledCount ++ ;
345359 PlayniteApi . Database . Games . Update ( game ) ;
346- logger . Info ( string . Format ( "Set \" {0}\" as installed" , game . Name ) ) ;
360+ _logger . Info ( string . Format ( "Set \" {0}\" as installed" , game . Name ) ) ;
347361 }
348362 }
349363 }
350364 } , new GlobalProgressOptions ( ResourceProvider . GetString ( "LOCNgfn_Enabler_UpdatingProgressMessage" ) ) ) ;
351365
352- logger . Info ( $ "Found { enabledGamesCount } enabled games. Added feature to { featureAddedCount } games and removed it from { featureRemovedCount } games. Set { setAsInstalledCount } as installed.") ;
366+ _logger . Info ( $ "Found { enabledGamesCount } enabled games. Added feature to { featureAddedCount } games and removed it from { featureRemovedCount } games. Set { setAsInstalledCount } as installed.") ;
353367 if ( showDialogs )
354368 {
355369 var results = string . Format ( ResourceProvider . GetString ( "LOCNgfn_Enabler_UpdateResults1Message" ) ,
356370 enabledGamesCount , featureName , featureAddedCount , featureName , featureRemovedCount ) ;
357- if ( settings . Settings . ShowPlayActionsOnLaunch )
371+ if ( _settings . Settings . ShowPlayActionsOnLaunch )
358372 {
359373 results += string . Format ( ResourceProvider . GetString ( "LOCNgfn_Enabler_UpdateResults3Message" ) , setAsInstalledCount ) ;
360374 }
@@ -370,20 +384,20 @@ public void UpdateDatabaseAndGamesStatus(bool showDialogs, bool updateDatabase =
370384
371385 private GeforceNowItemVariant GetDatabaseMatchingEntryForGame ( Game game )
372386 {
373- if ( pluginIdToAppStoreMapper . TryGetValue ( game . PluginId , out var appStore ) )
387+ if ( _pluginIdToAppStoreMapper . TryGetValue ( game . PluginId , out var appStore ) )
374388 {
375- if ( appStoresToMatchByName . Contains ( appStore ) )
389+ if ( _appStoresToMatchByName . Contains ( appStore ) )
376390 {
377391 var key = Tuple . Create ( appStore , SatinizeGameName ( game . Name ) ) ;
378- if ( detectionDictionary . TryGetValue ( key , out var itemVariant ) )
392+ if ( _detectionDictionary . TryGetValue ( key , out var itemVariant ) )
379393 {
380394 return itemVariant ;
381395 }
382396 }
383397 else
384398 {
385399 var key = Tuple . Create ( appStore , game . GameId ) ;
386- if ( detectionDictionary . TryGetValue ( key , out var itemVariant ) )
400+ if ( _detectionDictionary . TryGetValue ( key , out var itemVariant ) )
387401 {
388402 return itemVariant ;
389403 }
@@ -400,11 +414,11 @@ public override IEnumerable<PlayController> GetPlayActions(GetPlayActionsArgs ar
400414 {
401415 return new List < PlayController > ( )
402416 {
403- new NVIDIAGeForceNowEnablerPlayController ( game , game . GameId , geforceNowExecutablePath , geforceNowWorkingPath )
417+ new NVIDIAGeForceNowEnablerPlayController ( game , game . GameId , _geforceNowExecutablePath , _geforceNowWorkingPath )
404418 } ;
405419 }
406420
407- if ( ! settings . Settings . ShowPlayActionsOnLaunch )
421+ if ( ! _settings . Settings . ShowPlayActionsOnLaunch )
408422 {
409423 return null ;
410424 }
@@ -418,42 +432,42 @@ public override IEnumerable<PlayController> GetPlayActions(GetPlayActionsArgs ar
418432 // Library plugins set the game installation directory when they are
419433 // detected as installed. This is used to detect this and not show the Play
420434 // Action if it is detected as installed by the game library plugin.
421- if ( settings . Settings . OnlyShowActionsForNotLibInstalledGames && ! game . InstallDirectory . IsNullOrEmpty ( ) )
435+ if ( _settings . Settings . OnlyShowActionsForNotLibInstalledGames && ! game . InstallDirectory . IsNullOrEmpty ( ) )
422436 {
423- logger . Debug ( "Game install dir was not empty and was skipped" ) ;
437+ _logger . Debug ( "Game install dir was not empty and was skipped" ) ;
424438 return null ;
425439 }
426440
427- if ( ! FileSystem . FileExists ( geforceNowExecutablePath ) )
441+ if ( ! FileSystem . FileExists ( _geforceNowExecutablePath ) )
428442 {
429- logger . Debug ( "Geforce Now Executable was not detected" ) ;
443+ _logger . Debug ( "Geforce Now Executable was not detected" ) ;
430444 PlayniteApi . Notifications . Add ( new NotificationMessage (
431445 "gfnExeNotFound" ,
432- string . Format ( ResourceProvider . GetString ( "LOCNgfn_Enabler_NotificationMessage" ) , geforceNowExecutablePath ) ,
446+ string . Format ( ResourceProvider . GetString ( "LOCNgfn_Enabler_NotificationMessage" ) , _geforceNowExecutablePath ) ,
433447 NotificationType . Error ,
434448 ( ) => ProcessStarter . StartUrl ( @"https://github.com/darklinkpower/PlayniteExtensionsCollection/wiki/NVIDIA-GeForce-NOW-Enabler#nvidia-geforce-now-executable-not-found-error-notification" )
435449 ) ) ;
436450 return null ;
437451 }
438452
439- if ( ! detectionDictionary . HasItems ( ) )
453+ if ( ! _detectionDictionary . HasItems ( ) )
440454 {
441- logger . Debug ( "Supported list was not set" ) ;
455+ _logger . Debug ( "Supported list was not set" ) ;
442456 return null ;
443457 }
444458
445459 var supportedGame = GetDatabaseMatchingEntryForGame ( game ) ;
446460 if ( supportedGame != null )
447461 {
448- logger . Debug ( $ "Database entry with id { supportedGame . Id } found on startup for game { game . Name } ") ;
462+ _logger . Debug ( $ "Database entry with id { supportedGame . Id } found on startup for game { game . Name } ") ;
449463 return new List < PlayController > ( )
450464 {
451- new NVIDIAGeForceNowEnablerPlayController ( game , supportedGame . Id . ToString ( ) , geforceNowExecutablePath , geforceNowWorkingPath )
465+ new NVIDIAGeForceNowEnablerPlayController ( game , supportedGame . Id . ToString ( ) , _geforceNowExecutablePath , _geforceNowWorkingPath )
452466 } ;
453467 }
454468 else
455469 {
456- logger . Debug ( $ "Database entry with for { game . Name } with pluginId { game . PluginId } not found") ;
470+ _logger . Debug ( $ "Database entry with for { game . Name } with pluginId { game . PluginId } not found") ;
457471 }
458472
459473 return null ;
0 commit comments