From 127f0cbb084b26bfa29244b513f2a3d8dd19725a Mon Sep 17 00:00:00 2001
From: Daniel <790119+DanTheMan827@users.noreply.github.com>
Date: Fri, 7 Apr 2023 19:09:00 -0500
Subject: [PATCH 1/3] Switch to SharpCompress
---
.../InstallController.cs | 66 +---
.../LANCommander.PlaynitePlugin.csproj | 14 +-
.../LANCommanderLibraryPlugin.cs | 18 +-
.../Services/GameSaveService.cs | 120 +++----
.../TrackableStream.cs | 325 ++++++++++++++++++
.../UninstallController.cs | 11 +-
LANCommander.Playnite.Extension/app.config | 2 +-
.../packages.config | 5 +-
8 files changed, 407 insertions(+), 154 deletions(-)
create mode 100644 LANCommander.Playnite.Extension/TrackableStream.cs
diff --git a/LANCommander.Playnite.Extension/InstallController.cs b/LANCommander.Playnite.Extension/InstallController.cs
index 44c3923..1f621fe 100644
--- a/LANCommander.Playnite.Extension/InstallController.cs
+++ b/LANCommander.Playnite.Extension/InstallController.cs
@@ -1,23 +1,17 @@
-using Playnite.SDK;
-using Playnite.SDK.Models;
-using Playnite.SDK.Plugins;
+using LANCommander.PlaynitePlugin.Helpers;
using LANCommander.SDK.Enums;
using LANCommander.SDK.Extensions;
+using LANCommander.SDK.Models;
+using Playnite.SDK;
+using Playnite.SDK.Models;
+using Playnite.SDK.Plugins;
+using SharpCompress.Common;
+using SharpCompress.Readers;
using System;
-using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using ICSharpCode.SharpZipLib.Zip;
-using ICSharpCode.SharpZipLib.Core;
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
{
@@ -153,45 +147,23 @@ namespace LANCommander.PlaynitePlugin
Plugin.PlayniteApi.Dialogs.ActivateGlobalProgress(progress =>
{
- ZipFile file = null;
+ Directory.CreateDirectory(destination);
- try
+ using (var fs = File.OpenRead(archivePath))
+ using (var ts = new TrackableStream(fs))
+ using (var reader = ReaderFactory.Open(ts))
{
- FileStream fs = File.OpenRead(archivePath);
-
- file = new ZipFile(fs);
-
- progress.ProgressMaxValue = file.Count;
-
- foreach (ZipEntry entry in file)
+ progress.ProgressMaxValue = ts.Length;
+ ts.OnProgress += (pos, len) =>
{
- if (!entry.IsFile)
- continue;
+ progress.CurrentProgressValue = pos;
+ };
- byte[] buffer = new byte[4096];
- var zipStream = file.GetInputStream(entry);
-
- var entryDestination = Path.Combine(destination, entry.Name);
- var entryDirectory = Path.GetDirectoryName(entryDestination);
-
- if (!String.IsNullOrWhiteSpace(entryDirectory))
- Directory.CreateDirectory(entryDirectory);
-
- using (FileStream streamWriter = File.Create(entryDestination))
- {
- StreamUtils.Copy(zipStream, streamWriter, buffer);
- }
-
- progress.CurrentProgressValue = entry.ZipFileIndex;
- }
- }
- finally
- {
- if (file != null)
+ reader.WriteAllToDirectory(destination, new ExtractionOptions()
{
- file.IsStreamOwner = true;
- file.Close();
- }
+ ExtractFullPath = true,
+ Overwrite = true
+ });
}
},
new GlobalProgressOptions($"Extracting {game.Title}...")
diff --git a/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj b/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj
index 9f42d54..bc92634 100644
--- a/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj
+++ b/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj
@@ -34,9 +34,6 @@
..\packages\rix0rrr.BeaconLib.1.0.2\lib\net40\BeaconLib.dll
-
- ..\packages\SharpZipLib.1.4.2\lib\netstandard2.0\ICSharpCode.SharpZipLib.dll
-
..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
@@ -48,6 +45,9 @@
..\packages\RestSharp.106.15.0\lib\net452\RestSharp.dll
+
+ ..\packages\SharpCompress.0.33.0\lib\net462\SharpCompress.dll
+
..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
@@ -64,8 +64,11 @@
..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
-
- ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
+
+
+ ..\packages\System.Text.Encoding.CodePages.7.0.0\lib\net462\System.Text.Encoding.CodePages.dll
..\packages\System.Text.Encodings.Web.5.0.0\lib\net461\System.Text.Encodings.Web.dll
@@ -93,6 +96,7 @@
+
diff --git a/LANCommander.Playnite.Extension/LANCommanderLibraryPlugin.cs b/LANCommander.Playnite.Extension/LANCommanderLibraryPlugin.cs
index 8d0c32e..9530dd6 100644
--- a/LANCommander.Playnite.Extension/LANCommanderLibraryPlugin.cs
+++ b/LANCommander.Playnite.Extension/LANCommanderLibraryPlugin.cs
@@ -1,28 +1,17 @@
-using ICSharpCode.SharpZipLib.Core;
-using ICSharpCode.SharpZipLib.Zip;
-using LANCommander.PlaynitePlugin.Extensions;
+using LANCommander.PlaynitePlugin.Extensions;
using LANCommander.PlaynitePlugin.Services;
-using LANCommander.SDK;
using Playnite.SDK;
using Playnite.SDK.Events;
using Playnite.SDK.Models;
using Playnite.SDK.Plugins;
using System;
-using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Net.NetworkInformation;
-using System.Text;
-using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
-using System.Windows.Data;
using System.Windows.Media;
-using YamlDotNet.Serialization;
-using YamlDotNet.Serialization.NamingConventions;
using PN = Playnite;
namespace LANCommander.PlaynitePlugin
@@ -294,9 +283,10 @@ namespace LANCommander.PlaynitePlugin
FontSize = 16,
FontFamily = ResourceProvider.GetResource("FontIcoFont") as FontFamily,
Padding = new Thickness(10, 0, 10, 0),
-
+
},
- Activated = () => {
+ Activated = () =>
+ {
ShowNameChangeWindow();
}
};
diff --git a/LANCommander.Playnite.Extension/Services/GameSaveService.cs b/LANCommander.Playnite.Extension/Services/GameSaveService.cs
index 0a9dba7..bf9cbe5 100644
--- a/LANCommander.Playnite.Extension/Services/GameSaveService.cs
+++ b/LANCommander.Playnite.Extension/Services/GameSaveService.cs
@@ -1,16 +1,17 @@
-using ICSharpCode.SharpZipLib.Zip;
-using LANCommander.SDK;
+using LANCommander.SDK;
+using Playnite.SDK;
using Playnite.SDK.Models;
+using SharpCompress.Archives;
+using SharpCompress.Archives.Zip;
+using SharpCompress.Common;
+using SharpCompress.Readers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
-using System.Threading.Tasks;
-using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization;
-using ICSharpCode.SharpZipLib.Core;
-using Playnite.SDK;
+using YamlDotNet.Serialization.NamingConventions;
namespace LANCommander.PlaynitePlugin.Services
{
@@ -20,7 +21,8 @@ namespace LANCommander.PlaynitePlugin.Services
private readonly IPlayniteAPI PlayniteApi;
private readonly PowerShellRuntime PowerShellRuntime;
- internal GameSaveService(LANCommanderClient lanCommander, IPlayniteAPI playniteApi, PowerShellRuntime powerShellRuntime) {
+ internal GameSaveService(LANCommanderClient lanCommander, IPlayniteAPI playniteApi, PowerShellRuntime powerShellRuntime)
+ {
LANCommander = lanCommander;
PlayniteApi = playniteApi;
PowerShellRuntime = powerShellRuntime;
@@ -166,9 +168,9 @@ namespace LANCommander.PlaynitePlugin.Services
var manifest = deserializer.Deserialize(File.ReadAllText(manifestPath));
var temp = Path.GetTempFileName();
- using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(temp)))
+ using (var archive = ZipArchive.Create())
{
- zipStream.SetLevel(5);
+ archive.DeflateCompressionLevel = SharpCompress.Compressors.Deflate.CompressionLevel.BestCompression;
#region Add files from defined paths
foreach (var savePath in manifest.SavePaths.Where(sp => sp.Type == "File"))
@@ -177,18 +179,27 @@ namespace LANCommander.PlaynitePlugin.Services
if (Directory.Exists(localPath))
{
- AddDirectoryToZip(zipStream, localPath, localPath, savePath.Id);
+ AddDirectoryToZip(archive, localPath, localPath, savePath.Id);
}
else if (File.Exists(localPath))
{
- var entry = new ZipEntry(Path.Combine(savePath.Id.ToString(), savePath.Path.Replace("{InstallDir}/", "")));
+ archive.AddEntry(Path.Combine(savePath.Id.ToString(), savePath.Path.Replace("{InstallDir}/", "")), localPath);
+ }
+ }
+ #endregion
- zipStream.PutNextEntry(entry);
+ #region Add files from defined paths
+ foreach (var savePath in manifest.SavePaths.Where(sp => sp.Type == "File"))
+ {
+ var localPath = Environment.ExpandEnvironmentVariables(savePath.Path.Replace('/', '\\').Replace("{InstallDir}", game.InstallDirectory));
- byte[] buffer = File.ReadAllBytes(localPath);
-
- zipStream.Write(buffer, 0, buffer.Length);
- zipStream.CloseEntry();
+ if (Directory.Exists(localPath))
+ {
+ AddDirectoryToZip(archive, localPath, localPath, savePath.Id);
+ }
+ else if (File.Exists(localPath))
+ {
+ archive.AddEntry(Path.Combine(savePath.Id.ToString(), savePath.Path.Replace("{InstallDir}/", "")), localPath);
}
}
#endregion
@@ -218,47 +229,32 @@ namespace LANCommander.PlaynitePlugin.Services
File.Delete(tempRegFile);
}
- zipStream.PutNextEntry(new ZipEntry("_registry.reg"));
-
- byte[] regBuffer = Encoding.UTF8.GetBytes(exportFile.ToString());
-
- zipStream.Write(regBuffer, 0, regBuffer.Length);
- zipStream.CloseEntry();
+ archive.AddEntry("_registry.reg", new MemoryStream(Encoding.UTF8.GetBytes(exportFile.ToString())), true);
}
#endregion
- var manifestEntry = new ZipEntry("_manifest.yml");
+ archive.AddEntry("_manifest.yml", manifestPath);
- zipStream.PutNextEntry(manifestEntry);
+ using (var ms = new MemoryStream())
+ {
+ archive.SaveTo(ms);
- byte[] manifestBuffer = File.ReadAllBytes(manifestPath);
+ ms.Seek(0, SeekOrigin.Begin);
- zipStream.Write(manifestBuffer, 0, manifestBuffer.Length);
- zipStream.CloseEntry();
+ var save = LANCommander.UploadSave(game.GameId, ms.ToArray());
+ }
}
-
- var save = LANCommander.UploadSave(game.GameId, File.ReadAllBytes(temp));
-
- File.Delete(temp);
}
}
- private void AddDirectoryToZip(ZipOutputStream zipStream, string path, string workingDirectory, Guid pathId)
+ private void AddDirectoryToZip(ZipArchive zipArchive, string path, string workingDirectory, Guid pathId)
{
foreach (var file in Directory.GetFiles(path))
{
// Oh man is this a hack. We should be removing only the working directory from the start,
// but we're making the assumption that the working dir put in actually prefixes the path.
// Also wtf, that Path.Combine is stripping the pathId out?
- var entry = new ZipEntry(Path.Combine(pathId.ToString(), path.Substring(workingDirectory.Length), Path.GetFileName(file)));
-
- zipStream.PutNextEntry(entry);
-
- byte[] buffer = File.ReadAllBytes(file);
-
- zipStream.Write(buffer, 0, buffer.Length);
-
- zipStream.CloseEntry();
+ zipArchive.AddEntry(Path.Combine(pathId.ToString(), path.Substring(workingDirectory.Length), Path.GetFileName(file)), file);
}
foreach (var child in Directory.GetDirectories(path))
@@ -269,47 +265,21 @@ namespace LANCommander.PlaynitePlugin.Services
//zipStream.PutNextEntry(entry);
//zipStream.CloseEntry();
- AddDirectoryToZip(zipStream, child, workingDirectory, pathId);
+ AddDirectoryToZip(zipArchive, child, workingDirectory, pathId);
}
}
private void ExtractFilesFromZip(string zipPath, string destination)
{
- ZipFile file = null;
-
- try
+ using (var fs = File.OpenRead(zipPath))
+ using (var ts = new TrackableStream(fs))
+ using (var reader = ReaderFactory.Open(ts))
{
- FileStream fs = File.OpenRead(zipPath);
-
- file = new ZipFile(fs);
-
- foreach (ZipEntry entry in file)
+ reader.WriteAllToDirectory(destination, new ExtractionOptions()
{
- if (!entry.IsFile)
- continue;
-
- byte[] buffer = new byte[4096];
- var zipStream = file.GetInputStream(entry);
-
- var entryDestination = Path.Combine(destination, entry.Name);
- var entryDirectory = Path.GetDirectoryName(entryDestination);
-
- if (!String.IsNullOrWhiteSpace(entryDirectory))
- Directory.CreateDirectory(entryDirectory);
-
- using (FileStream streamWriter = File.Create(entryDestination))
- {
- StreamUtils.Copy(zipStream, streamWriter, buffer);
- }
- }
- }
- finally
- {
- if (file != null)
- {
- file.IsStreamOwner = true;
- file.Close();
- }
+ ExtractFullPath = true,
+ Overwrite = true
+ });
}
}
}
diff --git a/LANCommander.Playnite.Extension/TrackableStream.cs b/LANCommander.Playnite.Extension/TrackableStream.cs
new file mode 100644
index 0000000..e7b0c72
--- /dev/null
+++ b/LANCommander.Playnite.Extension/TrackableStream.cs
@@ -0,0 +1,325 @@
+using System.IO;
+
+namespace LANCommander.PlaynitePlugin
+{
+ internal class TrackableStream : MemoryStream
+ {
+ public delegate void OnProgressDelegate(long Position, long Length);
+ public event OnProgressDelegate OnProgress = delegate { };
+ private long internalStreamProgress = 0;
+ private Stream internalStream;
+
+ //
+ // Summary:
+ // Initializes a new instance of the TrackableStream class with an expandable
+ // capacity initialized to zero.
+ public TrackableStream() : base() { }
+
+ //
+ // Summary:
+ // Initializes a new instance of the TrackableStream class with the contents of stream.
+ // capacity initialized to zero.
+ public TrackableStream(Stream stream) : base()
+ {
+ internalStream = stream;
+ }
+
+ //
+ // Summary:
+ // Initializes a new instance of the TrackableStream class with an expandable
+ // capacity initialized as specified.
+ //
+ // Parameters:
+ // capacity:
+ // The initial size of the internal array in bytes.
+ //
+ // Exceptions:
+ // T:System.ArgumentOutOfRangeException:
+ // capacity is negative.
+ public TrackableStream(int capacity) : base(capacity) { }
+
+ //
+ // Summary:
+ // Initializes a new non-resizable instance of the TrackableStream class
+ // based on the specified byte array.
+ //
+ // Parameters:
+ // buffer:
+ // The array of unsigned bytes from which to create the current stream.
+ //
+ // Exceptions:
+ // T:System.ArgumentNullException:
+ // buffer is null.
+ public TrackableStream(byte[] buffer) : base(buffer) { }
+
+ //
+ // Summary:
+ // Initializes a new non-resizable instance of the TrackableStream class
+ // based on the specified byte array with the TrackableStream.CanWrite property
+ // set as specified.
+ //
+ // Parameters:
+ // buffer:
+ // The array of unsigned bytes from which to create this stream.
+ //
+ // writable:
+ // The setting of the TrackableStream.CanWrite property, which determines
+ // whether the stream supports writing.
+ //
+ // Exceptions:
+ // T:System.ArgumentNullException:
+ // buffer is null.
+ public TrackableStream(byte[] buffer, bool writable) : base(buffer, writable) { }
+
+ //
+ // Summary:
+ // Initializes a new non-resizable instance of the TrackableStream class
+ // based on the specified region (index) of a byte array.
+ //
+ // Parameters:
+ // buffer:
+ // The array of unsigned bytes from which to create this stream.
+ //
+ // index:
+ // The index into buffer at which the stream begins.
+ //
+ // count:
+ // The length of the stream in bytes.
+ //
+ // Exceptions:
+ // T:System.ArgumentNullException:
+ // buffer is null.
+ //
+ // T:System.ArgumentOutOfRangeException:
+ // index or count is less than zero.
+ //
+ // T:System.ArgumentException:
+ // The buffer length minus index is less than count.
+ public TrackableStream(byte[] buffer, int index, int count) : base(buffer, index, count) { }
+
+ //
+ // Summary:
+ // Initializes a new non-resizable instance of the TrackableStream class
+ // based on the specified region of a byte array, with the TrackableStream.CanWrite
+ // property set as specified.
+ //
+ // Parameters:
+ // buffer:
+ // The array of unsigned bytes from which to create this stream.
+ //
+ // index:
+ // The index in buffer at which the stream begins.
+ //
+ // count:
+ // The length of the stream in bytes.
+ //
+ // writable:
+ // The setting of the TrackableStream.CanWrite property, which determines
+ // whether the stream supports writing.
+ //
+ // Exceptions:
+ // T:System.ArgumentNullException:
+ // buffer is null.
+ //
+ // T:System.ArgumentOutOfRangeException:
+ // index or count are negative.
+ //
+ // T:System.ArgumentException:
+ // The buffer length minus index is less than count.
+ public TrackableStream(byte[] buffer, int index, int count, bool writable) : base(buffer, index, count, writable) { }
+
+ //
+ // Summary:
+ // Initializes a new instance of the TrackableStream class based on the specified
+ // region of a byte array, with the TrackableStream.CanWrite property set
+ // as specified, and the ability to call TrackableStream.GetBuffer set as
+ // specified.
+ //
+ // Parameters:
+ // buffer:
+ // The array of unsigned bytes from which to create this stream.
+ //
+ // index:
+ // The index into buffer at which the stream begins.
+ //
+ // count:
+ // The length of the stream in bytes.
+ //
+ // writable:
+ // The setting of the TrackableStream.CanWrite property, which determines
+ // whether the stream supports writing.
+ //
+ // publiclyVisible:
+ // true to enable TrackableStream.GetBuffer, which returns the unsigned byte
+ // array from which the stream was created; otherwise, false.
+ //
+ // Exceptions:
+ // T:System.ArgumentNullException:
+ // buffer is null.
+ //
+ // T:System.ArgumentOutOfRangeException:
+ // index or count is negative.
+ //
+ // T:System.ArgumentException:
+ // The buffer length minus index is less than count.
+ public TrackableStream(byte[] buffer, int index, int count, bool writable, bool publiclyVisible) : base(buffer, index, count, writable, publiclyVisible) { }
+
+ //
+ // Summary:
+ // Writes a block of bytes to the current stream using data read from a buffer.
+ //
+ // Parameters:
+ // buffer:
+ // The buffer to write data from.
+ //
+ // offset:
+ // The zero-based byte offset in buffer at which to begin copying bytes to the current
+ // stream.
+ //
+ // count:
+ // The maximum number of bytes to write.
+ //
+ // Exceptions:
+ // T:System.ArgumentNullException:
+ // buffer is null.
+ //
+ // T:System.NotSupportedException:
+ // The stream does not support writing. For additional information see System.IO.Stream.CanWrite.-or-
+ // The current position is closer than count bytes to the end of the stream, and
+ // the capacity cannot be modified.
+ //
+ // T:System.ArgumentException:
+ // offset subtracted from the buffer length is less than count.
+ //
+ // T:System.ArgumentOutOfRangeException:
+ // offset or count are negative.
+ //
+ // T:System.IO.IOException:
+ // An I/O error occurs.
+ //
+ // T:System.ObjectDisposedException:
+ // The current stream instance is closed.
+ public override void Write(byte[] array, int offset, int count)
+ {
+ if (internalStream is Stream)
+ {
+ internalStream.Write(array, offset, count);
+ OnProgress(internalStream.Position, internalStream.Length);
+ }
+ else
+ {
+ base.Write(array, offset, count);
+ OnProgress(this.Position, this.Length);
+ }
+ }
+
+ //
+ // Summary:
+ // Writes a byte to the current stream at the current position.
+ //
+ // Parameters:
+ // value:
+ // The byte to write.
+ //
+ // Exceptions:
+ // T:System.NotSupportedException:
+ // The stream does not support writing. For additional information see System.IO.Stream.CanWrite.-or-
+ // The current position is at the end of the stream, and the capacity cannot be
+ // modified.
+ //
+ // T:System.ObjectDisposedException:
+ // The current stream is closed.
+ public override void WriteByte(byte value)
+ {
+ if (internalStream is Stream)
+ {
+ internalStream.WriteByte(value);
+ OnProgress(internalStream.Position, internalStream.Length);
+ }
+ else
+ {
+ base.WriteByte(value);
+ OnProgress(this.Position, this.Length);
+ }
+ }
+
+ //
+ // Summary:
+ // Reads a block of bytes from the current stream and writes the data to a buffer.
+ //
+ // Parameters:
+ // buffer:
+ // When this method returns, contains the specified byte array with the values between
+ // offset and (offset + count - 1) replaced by the characters read from the current
+ // stream.
+ //
+ // offset:
+ // The zero-based byte offset in buffer at which to begin storing data from the
+ // current stream.
+ //
+ // count:
+ // The maximum number of bytes to read.
+ //
+ // Returns:
+ // The total number of bytes written into the buffer. This can be less than the
+ // number of bytes requested if that number of bytes are not currently available,
+ // or zero if the end of the stream is reached before any bytes are read.
+ //
+ // Exceptions:
+ // T:System.ArgumentNullException:
+ // buffer is null.
+ //
+ // T:System.ArgumentOutOfRangeException:
+ // offset or count is negative.
+ //
+ // T:System.ArgumentException:
+ // offset subtracted from the buffer length is less than count.
+ //
+ // T:System.ObjectDisposedException:
+ // The current stream instance is closed.
+ public override int Read(byte[] array, int offset, int count)
+ {
+ int r;
+ if (internalStream is Stream)
+ {
+ r = internalStream.Read(array, offset, count);
+ internalStreamProgress += r;
+ OnProgress(internalStreamProgress, this.Length);
+ }
+ else
+ {
+ r = base.Read(array, offset, count);
+ OnProgress(this.Position, this.Length);
+ }
+
+ return r;
+ }
+
+ //
+ // Summary:
+ // Reads a byte from the current stream.
+ //
+ // Returns:
+ // The byte cast to a System.Int32, or -1 if the end of the stream has been reached.
+ //
+ // Exceptions:
+ // T:System.ObjectDisposedException:
+ // The current stream instance is closed.
+ public override int ReadByte()
+ {
+ int r;
+ if (internalStream is Stream)
+ {
+ r = internalStream.ReadByte();
+ internalStreamProgress += r;
+ OnProgress(internalStreamProgress, this.Length);
+ }
+ else
+ {
+ r = base.ReadByte();
+ OnProgress(this.Position, this.Length);
+ }
+ return r;
+ }
+ }
+}
diff --git a/LANCommander.Playnite.Extension/UninstallController.cs b/LANCommander.Playnite.Extension/UninstallController.cs
index 158e111..0bb28e8 100644
--- a/LANCommander.Playnite.Extension/UninstallController.cs
+++ b/LANCommander.Playnite.Extension/UninstallController.cs
@@ -1,17 +1,8 @@
-using Playnite.SDK;
+using LANCommander.SDK.Enums;
using Playnite.SDK.Models;
using Playnite.SDK.Plugins;
-using LANCommander.SDK.Extensions;
using System;
-using System.Collections.Generic;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using ICSharpCode.SharpZipLib.Zip;
-using ICSharpCode.SharpZipLib.Core;
-using LANCommander.SDK.Enums;
namespace LANCommander.PlaynitePlugin
{
diff --git a/LANCommander.Playnite.Extension/app.config b/LANCommander.Playnite.Extension/app.config
index 6314000..8adb46d 100644
--- a/LANCommander.Playnite.Extension/app.config
+++ b/LANCommander.Playnite.Extension/app.config
@@ -4,7 +4,7 @@
-
+
diff --git a/LANCommander.Playnite.Extension/packages.config b/LANCommander.Playnite.Extension/packages.config
index fe9fb0b..aa5952d 100644
--- a/LANCommander.Playnite.Extension/packages.config
+++ b/LANCommander.Playnite.Extension/packages.config
@@ -6,11 +6,12 @@
-
+
-
+
+
From cb770f8dab42d4c70305fde3fad904592a0e88dc Mon Sep 17 00:00:00 2001
From: Daniel <790119+DanTheMan827@users.noreply.github.com>
Date: Fri, 7 Apr 2023 20:08:03 -0500
Subject: [PATCH 2/3] Add DownloadAndExtract
---
.../InstallController.cs | 54 ++++++++++++++-----
.../LANCommanderClient.cs | 23 ++++++--
.../TrackableStream.cs | 21 ++++++--
3 files changed, 79 insertions(+), 19 deletions(-)
diff --git a/LANCommander.Playnite.Extension/InstallController.cs b/LANCommander.Playnite.Extension/InstallController.cs
index 1f621fe..f4b206c 100644
--- a/LANCommander.Playnite.Extension/InstallController.cs
+++ b/LANCommander.Playnite.Extension/InstallController.cs
@@ -39,19 +39,9 @@ namespace LANCommander.PlaynitePlugin
var gameId = Guid.Parse(Game.GameId);
var game = Plugin.LANCommander.GetGame(gameId);
- string tempDownloadLocation;
-
- if (Plugin.DownloadCache.ContainsKey(gameId))
- tempDownloadLocation = Plugin.DownloadCache[gameId];
- else
- {
- tempDownloadLocation = Download(game);
- Plugin.DownloadCache[gameId] = tempDownloadLocation;
- }
-
var installDirectory = RetryHelper.RetryOnException(10, TimeSpan.FromMilliseconds(500), "", () =>
{
- return Extract(game, tempDownloadLocation);
+ return DownloadAndExtract(game);
});
if (installDirectory == "")
@@ -97,11 +87,51 @@ namespace LANCommander.PlaynitePlugin
Plugin.UpdateGame(manifest, gameId);
Plugin.DownloadCache.Remove(gameId);
- File.Delete(tempDownloadLocation);
InvokeOnInstalled(new GameInstalledEventArgs(installInfo));
}
+ private string DownloadAndExtract(LANCommander.SDK.Models.Game game)
+ {
+ if (game == null)
+ {
+ throw new Exception("Game failed to download!");
+ }
+
+ var destination = Path.Combine(Plugin.Settings.InstallDirectory, game.Title.SanitizeFilename());
+
+ Plugin.PlayniteApi.Dialogs.ActivateGlobalProgress(progress =>
+ {
+ Directory.CreateDirectory(destination);
+ progress.ProgressMaxValue = 100;
+ progress.CurrentProgressValue = 0;
+
+ using (var gameStream = Plugin.LANCommander.StreamGame(game.Id))
+ using (var reader = ReaderFactory.Open(gameStream))
+ {
+ progress.ProgressMaxValue = gameStream.Length;
+
+ gameStream.OnProgress += (pos, len) =>
+ {
+ progress.CurrentProgressValue = pos;
+ };
+
+ reader.WriteAllToDirectory(destination, new ExtractionOptions()
+ {
+ ExtractFullPath = true,
+ Overwrite = true
+ });
+ }
+ },
+ new GlobalProgressOptions($"Downloading {game.Title}...")
+ {
+ IsIndeterminate = false,
+ Cancelable = false,
+ });
+
+ return destination;
+ }
+
private string Download(LANCommander.SDK.Models.Game game)
{
string tempFile = String.Empty;
diff --git a/LANCommander.Playnite.Extension/LANCommanderClient.cs b/LANCommander.Playnite.Extension/LANCommanderClient.cs
index 787148e..990e825 100644
--- a/LANCommander.Playnite.Extension/LANCommanderClient.cs
+++ b/LANCommander.Playnite.Extension/LANCommanderClient.cs
@@ -1,7 +1,6 @@
using LANCommander.SDK;
using LANCommander.SDK.Models;
using RestSharp;
-using RestSharp.Extensions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -9,10 +8,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
-using System.Text;
using System.Threading.Tasks;
-using System.Windows.Media.Converters;
-using YamlDotNet.Core;
namespace LANCommander.PlaynitePlugin
{
@@ -64,6 +60,20 @@ namespace LANCommander.PlaynitePlugin
return tempFile;
}
+ private TrackableStream StreamRequest(string route)
+ {
+ route = route.TrimStart('/');
+
+ var client = new WebClient();
+ var tempFile = Path.GetTempFileName();
+
+ client.Headers.Add("Authorization", $"Bearer {Token.AccessToken}");
+
+ var ws = client.OpenRead(new Uri($"{Client.BaseUrl}{route}"));
+
+ return new TrackableStream(ws, true, Convert.ToInt64(client.ResponseHeaders["Content-Length"]));
+ }
+
public async Task AuthenticateAsync(string username, string password)
{
var response = await Client.ExecuteAsync(new RestRequest("/api/Auth", Method.POST).AddJsonBody(new AuthRequest()
@@ -166,6 +176,11 @@ namespace LANCommander.PlaynitePlugin
return DownloadRequest($"/api/Games/{id}/Download", progressHandler, completeHandler);
}
+ public TrackableStream StreamGame(Guid id)
+ {
+ return StreamRequest($"/api/Games/{id}/Download");
+ }
+
public string DownloadArchive(Guid id, Action progressHandler, Action completeHandler)
{
return DownloadRequest($"/api/Archives/Download/{id}", progressHandler, completeHandler);
diff --git a/LANCommander.Playnite.Extension/TrackableStream.cs b/LANCommander.Playnite.Extension/TrackableStream.cs
index e7b0c72..cff27f8 100644
--- a/LANCommander.Playnite.Extension/TrackableStream.cs
+++ b/LANCommander.Playnite.Extension/TrackableStream.cs
@@ -1,13 +1,16 @@
-using System.IO;
+using System;
+using System.IO;
namespace LANCommander.PlaynitePlugin
{
- internal class TrackableStream : MemoryStream
+ internal class TrackableStream : MemoryStream, IDisposable
{
public delegate void OnProgressDelegate(long Position, long Length);
public event OnProgressDelegate OnProgress = delegate { };
private long internalStreamProgress = 0;
private Stream internalStream;
+ private bool disposeStream = false;
+ private long? streamLength;
//
// Summary:
@@ -19,9 +22,11 @@ namespace LANCommander.PlaynitePlugin
// Summary:
// Initializes a new instance of the TrackableStream class with the contents of stream.
// capacity initialized to zero.
- public TrackableStream(Stream stream) : base()
+ public TrackableStream(Stream stream, bool disposeStream = false, long? streamLength = null) : base()
{
internalStream = stream;
+ this.disposeStream = disposeStream;
+ this.streamLength = streamLength;
}
//
@@ -321,5 +326,15 @@ namespace LANCommander.PlaynitePlugin
}
return r;
}
+
+ public void Dispose()
+ {
+ if (disposeStream)
+ {
+ internalStream.Dispose();
+ }
+ }
+
+ public long Length => streamLength ?? internalStream.Length;
}
}
From f05005460fd41a74409fae32644daa83e68e4193 Mon Sep 17 00:00:00 2001
From: Daniel <790119+DanTheMan827@users.noreply.github.com>
Date: Sat, 8 Apr 2023 15:47:01 -0500
Subject: [PATCH 3/3] Delete install path on install error
---
.../InstallController.cs | 38 ++++++++++++-------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/LANCommander.Playnite.Extension/InstallController.cs b/LANCommander.Playnite.Extension/InstallController.cs
index f4b206c..d9f4f87 100644
--- a/LANCommander.Playnite.Extension/InstallController.cs
+++ b/LANCommander.Playnite.Extension/InstallController.cs
@@ -102,25 +102,35 @@ namespace LANCommander.PlaynitePlugin
Plugin.PlayniteApi.Dialogs.ActivateGlobalProgress(progress =>
{
- Directory.CreateDirectory(destination);
- progress.ProgressMaxValue = 100;
- progress.CurrentProgressValue = 0;
-
- using (var gameStream = Plugin.LANCommander.StreamGame(game.Id))
- using (var reader = ReaderFactory.Open(gameStream))
+ try
{
- progress.ProgressMaxValue = gameStream.Length;
+ Directory.CreateDirectory(destination);
+ progress.ProgressMaxValue = 100;
+ progress.CurrentProgressValue = 0;
- gameStream.OnProgress += (pos, len) =>
+ using (var gameStream = Plugin.LANCommander.StreamGame(game.Id))
+ using (var reader = ReaderFactory.Open(gameStream))
{
- progress.CurrentProgressValue = pos;
- };
+ progress.ProgressMaxValue = gameStream.Length;
- reader.WriteAllToDirectory(destination, new ExtractionOptions()
+ gameStream.OnProgress += (pos, len) =>
+ {
+ progress.CurrentProgressValue = pos;
+ };
+
+ reader.WriteAllToDirectory(destination, new ExtractionOptions()
+ {
+ ExtractFullPath = true,
+ Overwrite = true
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+ if (Directory.Exists(destination))
{
- ExtractFullPath = true,
- Overwrite = true
- });
+ Directory.Delete(destination, true);
+ }
}
},
new GlobalProgressOptions($"Downloading {game.Title}...")