@@ -16,19 +16,15 @@ namespace OpenTweak.Services;
1616/// </summary>
1717public class GameScanner : IGameScanner
1818{
19- private readonly List < Game > _detectedGames = new ( ) ;
20-
2119 /// <summary>
2220 /// Scans all supported launchers and returns detected games.
2321 /// </summary>
2422 public async Task < List < Game > > ScanAllLaunchersAsync ( CancellationToken cancellationToken = default )
2523 {
26- _detectedGames . Clear ( ) ;
27-
2824 if ( cancellationToken . IsCancellationRequested )
29- return _detectedGames ;
25+ return new List < Game > ( ) ;
3026
31- var tasks = new List < Task >
27+ var tasks = new List < Task < List < Game > > >
3228 {
3329 Task . Run ( ( ) => ScanSteam ( cancellationToken ) , cancellationToken ) ,
3430 Task . Run ( ( ) => ScanEpicGames ( cancellationToken ) , cancellationToken ) ,
@@ -38,30 +34,30 @@ public async Task<List<Game>> ScanAllLaunchersAsync(CancellationToken cancellati
3834
3935 try
4036 {
41- await Task . WhenAll ( tasks ) ;
37+ var results = await Task . WhenAll ( tasks ) ;
38+ return results . SelectMany ( g => g ) . OrderBy ( g => g . Name ) . ToList ( ) ;
4239 }
4340 catch ( OperationCanceledException )
4441 {
45- // Ignore cancellation exceptions
42+ return new List < Game > ( ) ;
4643 }
47-
48- return _detectedGames . OrderBy ( g => g . Name ) . ToList ( ) ;
4944 }
5045
5146 #region Steam Scanner
5247
5348 /// <summary>
5449 /// Scans Steam libraries by parsing libraryfolders.vdf and appmanifest files.
5550 /// </summary>
56- private void ScanSteam ( CancellationToken cancellationToken )
51+ private List < Game > ScanSteam ( CancellationToken cancellationToken )
5752 {
53+ var games = new List < Game > ( ) ;
5854 try
5955 {
6056 var steamPaths = GetSteamLibraryPaths ( ) ;
6157
6258 foreach ( var libraryPath in steamPaths )
6359 {
64- if ( cancellationToken . IsCancellationRequested ) return ;
60+ if ( cancellationToken . IsCancellationRequested ) break ;
6561
6662 var steamAppsPath = Path . Combine ( libraryPath , "steamapps" ) ;
6763 if ( ! Directory . Exists ( steamAppsPath ) ) continue ;
@@ -70,15 +66,12 @@ private void ScanSteam(CancellationToken cancellationToken)
7066
7167 foreach ( var manifest in manifestFiles )
7268 {
73- if ( cancellationToken . IsCancellationRequested ) return ;
69+ if ( cancellationToken . IsCancellationRequested ) break ;
7470
7571 var game = ParseSteamManifest ( manifest , steamAppsPath ) ;
7672 if ( game != null )
7773 {
78- lock ( _detectedGames )
79- {
80- _detectedGames . Add ( game ) ;
81- }
74+ games . Add ( game ) ;
8275 }
8376 }
8477 }
@@ -87,6 +80,7 @@ private void ScanSteam(CancellationToken cancellationToken)
8780 {
8881 System . Diagnostics . Debug . WriteLine ( $ "Steam scan error: { ex . Message } ") ;
8982 }
83+ return games ;
9084 }
9185
9286 private List < string > GetSteamLibraryPaths ( )
@@ -171,36 +165,35 @@ private List<string> GetSteamLibraryPaths()
171165 /// <summary>
172166 /// Scans Epic Games by parsing .item manifest files.
173167 /// </summary>
174- private void ScanEpicGames ( CancellationToken cancellationToken )
168+ private List < Game > ScanEpicGames ( CancellationToken cancellationToken )
175169 {
170+ var games = new List < Game > ( ) ;
176171 try
177172 {
178173 var manifestsPath = Path . Combine (
179174 Environment . GetFolderPath ( Environment . SpecialFolder . CommonApplicationData ) ,
180175 "Epic" , "EpicGamesLauncher" , "Data" , "Manifests" ) ;
181176
182- if ( ! Directory . Exists ( manifestsPath ) ) return ;
177+ if ( ! Directory . Exists ( manifestsPath ) ) return games ;
183178
184179 var itemFiles = Directory . GetFiles ( manifestsPath , "*.item" ) ;
185180
186181 foreach ( var itemFile in itemFiles )
187182 {
188- if ( cancellationToken . IsCancellationRequested ) return ;
183+ if ( cancellationToken . IsCancellationRequested ) break ;
189184
190185 var game = ParseEpicManifest ( itemFile ) ;
191186 if ( game != null )
192187 {
193- lock ( _detectedGames )
194- {
195- _detectedGames . Add ( game ) ;
196- }
188+ games . Add ( game ) ;
197189 }
198190 }
199191 }
200192 catch ( Exception ex )
201193 {
202194 System . Diagnostics . Debug . WriteLine ( $ "Epic scan error: { ex . Message } ") ;
203195 }
196+ return games ;
204197 }
205198
206199 private Game ? ParseEpicManifest ( string itemPath )
@@ -246,8 +239,9 @@ private void ScanEpicGames(CancellationToken cancellationToken)
246239 /// <summary>
247240 /// Scans GOG Galaxy by reading registry keys.
248241 /// </summary>
249- private void ScanGOG ( CancellationToken cancellationToken )
242+ private List < Game > ScanGOG ( CancellationToken cancellationToken )
250243 {
244+ var games = new List < Game > ( ) ;
251245 try
252246 {
253247 // Check both 32-bit and 64-bit registry locations
@@ -259,14 +253,14 @@ private void ScanGOG(CancellationToken cancellationToken)
259253
260254 foreach ( var regPath in registryPaths )
261255 {
262- if ( cancellationToken . IsCancellationRequested ) return ;
256+ if ( cancellationToken . IsCancellationRequested ) break ;
263257
264258 using var gamesKey = Registry . LocalMachine . OpenSubKey ( regPath ) ;
265259 if ( gamesKey == null ) continue ;
266260
267261 foreach ( var gameIdStr in gamesKey . GetSubKeyNames ( ) )
268262 {
269- if ( cancellationToken . IsCancellationRequested ) return ;
263+ if ( cancellationToken . IsCancellationRequested ) break ;
270264
271265 using var gameKey = gamesKey . OpenSubKey ( gameIdStr ) ;
272266 if ( gameKey == null ) continue ;
@@ -281,24 +275,22 @@ private void ScanGOG(CancellationToken cancellationToken)
281275 if ( ! Directory . Exists ( gamePath ) )
282276 continue ;
283277
284- lock ( _detectedGames )
278+ games . Add ( new Game
285279 {
286- _detectedGames . Add ( new Game
287- {
288- Name = gameName ,
289- InstallPath = gamePath ,
290- LauncherType = LauncherType . GOG ,
291- AppId = gameId ?? gameIdStr ,
292- PCGWTitle = gameName
293- } ) ;
294- }
280+ Name = gameName ,
281+ InstallPath = gamePath ,
282+ LauncherType = LauncherType . GOG ,
283+ AppId = gameId ?? gameIdStr ,
284+ PCGWTitle = gameName
285+ } ) ;
295286 }
296287 }
297288 }
298289 catch ( Exception ex )
299290 {
300291 System . Diagnostics . Debug . WriteLine ( $ "GOG scan error: { ex . Message } ") ;
301292 }
293+ return games ;
302294 }
303295
304296 #endregion
@@ -308,8 +300,9 @@ private void ScanGOG(CancellationToken cancellationToken)
308300 /// <summary>
309301 /// Scans Xbox/Microsoft Store games (basic implementation).
310302 /// </summary>
311- private void ScanXbox ( CancellationToken cancellationToken )
303+ private List < Game > ScanXbox ( CancellationToken cancellationToken )
312304 {
305+ var games = new List < Game > ( ) ;
313306 try
314307 {
315308 // Xbox Game Pass games are in WindowsApps or XboxGames folders
@@ -322,30 +315,27 @@ private void ScanXbox(CancellationToken cancellationToken)
322315
323316 foreach ( var basePath in xboxPaths )
324317 {
325- if ( cancellationToken . IsCancellationRequested ) return ;
318+ if ( cancellationToken . IsCancellationRequested ) break ;
326319 if ( ! Directory . Exists ( basePath ) ) continue ;
327320
328321 // XboxGames folder has a simpler structure
329322 if ( basePath . EndsWith ( "XboxGames" ) )
330323 {
331324 foreach ( var gameDir in Directory . GetDirectories ( basePath ) )
332325 {
333- if ( cancellationToken . IsCancellationRequested ) return ;
326+ if ( cancellationToken . IsCancellationRequested ) break ;
334327
335328 var contentDir = Path . Combine ( gameDir , "Content" ) ;
336329 if ( Directory . Exists ( contentDir ) )
337330 {
338331 var gameName = Path . GetFileName ( gameDir ) ;
339- lock ( _detectedGames )
332+ games . Add ( new Game
340333 {
341- _detectedGames . Add ( new Game
342- {
343- Name = gameName ,
344- InstallPath = contentDir ,
345- LauncherType = LauncherType . Xbox ,
346- PCGWTitle = gameName
347- } ) ;
348- }
334+ Name = gameName ,
335+ InstallPath = contentDir ,
336+ LauncherType = LauncherType . Xbox ,
337+ PCGWTitle = gameName
338+ } ) ;
349339 }
350340 }
351341 }
@@ -355,6 +345,7 @@ private void ScanXbox(CancellationToken cancellationToken)
355345 {
356346 System . Diagnostics . Debug . WriteLine ( $ "Xbox scan error: { ex . Message } ") ;
357347 }
348+ return games ;
358349 }
359350
360351 #endregion
0 commit comments