Skip to content

Commit

Permalink
Merge #4200 Skip corrupted .acf files in Steam library
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Sep 27, 2024
2 parents 7568b2e + 6594a0e commit 286d3eb
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ All notable changes to this project will be documented in this file.

## v1.35.1

### Bugfixes

- [Core] Skip corrupted .acf files in Steam library (#4200 by: HebaruSan)

## v1.35.0 (Oberth)

Expand Down
16 changes: 16 additions & 0 deletions Core/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,22 @@ public static IEnumerable<Match> WithMatches(this IEnumerable<string> source, Re
=> source.Select(val => pattern.TryMatch(val, out Match? match) ? match : null)
.OfType<Match>();

/// <summary>
/// Apply a function to a sequence and handle any exceptions that are thrown
/// </summary>
/// <typeparam name="TSrc">Type of source sequence</typeparam>
/// <typeparam name="TDest">Type of destination sequence</typeparam>
/// <param name="source">Source sequence</param>
/// <param name="func">Function to apply to each item</param>
/// <param name="onThrow">Function to call if there's an exception</param>
/// <returns>Sequence of return values of given function</returns>
public static IEnumerable<TDest?> SelectWithCatch<TSrc, TDest>(this IEnumerable<TSrc> source,
Func<TSrc, TDest> func,
Func<TSrc, Exception, TDest?> onThrow)
where TDest : class
=> source.Select(item => Utilities.DefaultIfThrows(() => func(item),
exc => onThrow(item, exc)));

}

/// <summary>
Expand Down
11 changes: 9 additions & 2 deletions Core/SteamLibrary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

using log4net;
using ValveKeyValue;
using CKAN.Extensions;

namespace CKAN
{
Expand Down Expand Up @@ -57,8 +58,14 @@ public IEnumerable<Uri> GameAppURLs(DirectoryInfo gameDir)
private static IEnumerable<GameBase> LibraryPathGames(KVSerializer acfParser,
string appPath)
=> Directory.EnumerateFiles(appPath, "*.acf")
.Select(acfFile => acfParser.Deserialize<SteamGame>(File.OpenRead(acfFile))
.NormalizeDir(Path.Combine(appPath, "common")));
.SelectWithCatch(acfFile => acfParser.Deserialize<SteamGame>(File.OpenRead(acfFile))
.NormalizeDir(Path.Combine(appPath, "common")),
(acfFile, exc) =>
{
log.Warn($"Failed to parse {acfFile}:", exc);
return default;
})
.OfType<GameBase>();

private static IEnumerable<GameBase> ShortcutsFileGames(KVSerializer vdfParser,
string path)
Expand Down
14 changes: 11 additions & 3 deletions Core/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,23 @@ public static class Utilities
"nl-NL",
};

public static T? DefaultIfThrows<T>(Func<T?> func) where T : class
/// <summary>
/// Call a function and take a default action if it throws an exception
/// </summary>
/// <typeparam name="T">Return type of the function</typeparam>
/// <param name="func">Function to call</param>
/// <param name="onThrow">Function to call if an exception is thrown</param>
/// <returns>Return value of the function</returns>
public static T? DefaultIfThrows<T>(Func<T?> func,
Func<Exception, T?>? onThrow = null) where T : class
{
try
{
return func();
}
catch
catch (Exception exc)
{
return default;
return onThrow?.Invoke(exc) ?? default;
}
}

Expand Down

0 comments on commit 286d3eb

Please sign in to comment.