Added retry to writing manifest. Keep track of temporary download locations to avoid multiple downloads.

pull/19/head
Pat Hartl 2023-03-20 18:37:12 -05:00
parent a07416277b
commit 7c1f282feb
4 changed files with 78 additions and 7 deletions

View File

@ -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<T>(int maxAttempts, TimeSpan delay, T @default, Func<T> action)
{
int attempts = 0;
do
{
try
{
attempts++;
return action();
}
catch (Exception ex)
{
if (attempts >= maxAttempts)
return @default;
Task.Delay(delay).Wait();
}
} while (true);
}
}
}

View File

@ -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}...")

View File

@ -94,6 +94,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Extensions\MultiplayerInfoExtensions.cs" />
<Compile Include="Helpers\RetryHelper.cs" />
<Compile Include="PowerShellRuntime.cs" />
<Compile Include="UninstallController.cs" />
<Compile Include="InstallController.cs" />

View File

@ -34,6 +34,8 @@ namespace LANCommander.PlaynitePlugin
public override string Name => "LANCommander";
public override LibraryClient Client { get; } = new LANCommanderLibraryClient();
internal Dictionary<Guid, string> DownloadCache = new Dictionary<Guid, string>();
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<TopPanelItem> GetTopPanelItems()