diff --git a/LANCommander.Playnite.Extension/Helpers/RetryHelper.cs b/LANCommander.Playnite.Extension/Helpers/RetryHelper.cs new file mode 100644 index 0000000..7feb998 --- /dev/null +++ b/LANCommander.Playnite.Extension/Helpers/RetryHelper.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LANCommander.PlaynitePlugin.Helpers +{ + internal static class RetryHelper + { + internal static T RetryOnException(int maxAttempts, TimeSpan delay, T @default, Func action) + { + int attempts = 0; + + do + { + try + { + attempts++; + return action(); + } + catch (Exception ex) + { + if (attempts >= maxAttempts) + return @default; + + Task.Delay(delay).Wait(); + } + } while (true); + } + } +} diff --git a/LANCommander.Playnite.Extension/InstallController.cs b/LANCommander.Playnite.Extension/InstallController.cs index 8ef573e..4aabadb 100644 --- a/LANCommander.Playnite.Extension/InstallController.cs +++ b/LANCommander.Playnite.Extension/InstallController.cs @@ -16,6 +16,8 @@ using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; using LANCommander.SDK.Models; using System.Collections.ObjectModel; +using System.Web.Caching; +using LANCommander.PlaynitePlugin.Helpers; namespace LANCommander.PlaynitePlugin { @@ -41,13 +43,19 @@ namespace LANCommander.PlaynitePlugin } var gameId = Guid.Parse(Game.GameId); - var game = Plugin.LANCommander.GetGame(gameId); - var manifest = Plugin.LANCommander.GetGameManifest(gameId); - var tempFile = Download(game); + string tempDownloadLocation; - var installDirectory = Extract(game, tempFile); + if (Plugin.DownloadCache.ContainsKey(gameId)) + tempDownloadLocation = Plugin.DownloadCache[gameId]; + else + { + tempDownloadLocation = Download(game); + Plugin.DownloadCache[gameId] = tempDownloadLocation; + } + + var installDirectory = Extract(game, tempDownloadLocation); var installInfo = new GameInstallationData() { @@ -56,7 +64,19 @@ namespace LANCommander.PlaynitePlugin PlayniteGame.InstallDirectory = installDirectory; - WriteManifest(manifest, installDirectory); + SDK.GameManifest manifest = null; + + var writeManifestSuccess = RetryHelper.RetryOnException(10, TimeSpan.FromSeconds(1), false, () => + { + manifest = Plugin.LANCommander.GetGameManifest(gameId); + + WriteManifest(manifest, installDirectory); + + return true; + }); + + if (!writeManifestSuccess) + throw new Exception("Could not get or write the manifest file. Retry the install or check your connection."); SaveScript(game, installDirectory, ScriptType.Install); SaveScript(game, installDirectory, ScriptType.Uninstall); @@ -76,6 +96,9 @@ namespace LANCommander.PlaynitePlugin Plugin.UpdateGame(manifest, gameId); + Plugin.DownloadCache.Remove(gameId); + File.Delete(tempDownloadLocation); + InvokeOnInstalled(new GameInstalledEventArgs(installInfo)); } @@ -163,8 +186,6 @@ namespace LANCommander.PlaynitePlugin file.IsStreamOwner = true; file.Close(); } - - File.Delete(archivePath); } }, new GlobalProgressOptions($"Extracting {game.Title}...") diff --git a/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj b/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj index 2d33279..fedf56d 100644 --- a/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj +++ b/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj @@ -94,6 +94,7 @@ + diff --git a/LANCommander.Playnite.Extension/LANCommanderLibraryPlugin.cs b/LANCommander.Playnite.Extension/LANCommanderLibraryPlugin.cs index e8aed9c..cc3bb0c 100644 --- a/LANCommander.Playnite.Extension/LANCommanderLibraryPlugin.cs +++ b/LANCommander.Playnite.Extension/LANCommanderLibraryPlugin.cs @@ -34,6 +34,8 @@ namespace LANCommander.PlaynitePlugin public override string Name => "LANCommander"; public override LibraryClient Client { get; } = new LANCommanderLibraryClient(); + internal Dictionary DownloadCache = new Dictionary(); + public LANCommanderLibraryPlugin(IPlayniteAPI api) : base(api) { Properties = new LibraryPluginProperties @@ -227,6 +229,21 @@ namespace LANCommander.PlaynitePlugin ShowNameChangeWindow(); } }; + + yield return new MainMenuItem + { + Description = "Clear Download Cache", + Action = (args2) => + { + foreach (var gameId in DownloadCache.Keys) + { + File.Delete(DownloadCache[gameId]); + DownloadCache.Remove(gameId); + } + + PlayniteApi.Dialogs.ShowMessage("The download cache has been cleared and any temporary files have been deleted.", "Cache Cleared!", MessageBoxButton.OK); + } + }; } public override IEnumerable GetTopPanelItems()