Move save handling to separate service. Handle registry paths.
This commit is contained in:
parent
aa8aba154e
commit
2485fc7cb3
4 changed files with 297 additions and 201 deletions
|
@ -96,6 +96,7 @@
|
||||||
<Compile Include="Extensions\MultiplayerInfoExtensions.cs" />
|
<Compile Include="Extensions\MultiplayerInfoExtensions.cs" />
|
||||||
<Compile Include="Helpers\RetryHelper.cs" />
|
<Compile Include="Helpers\RetryHelper.cs" />
|
||||||
<Compile Include="PowerShellRuntime.cs" />
|
<Compile Include="PowerShellRuntime.cs" />
|
||||||
|
<Compile Include="Services\GameSaveService.cs" />
|
||||||
<Compile Include="UninstallController.cs" />
|
<Compile Include="UninstallController.cs" />
|
||||||
<Compile Include="InstallController.cs" />
|
<Compile Include="InstallController.cs" />
|
||||||
<Compile Include="LANCommanderClient.cs" />
|
<Compile Include="LANCommanderClient.cs" />
|
||||||
|
@ -145,5 +146,6 @@
|
||||||
<Name>LANCommander.SDK</Name>
|
<Name>LANCommander.SDK</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
|
@ -1,6 +1,7 @@
|
||||||
using ICSharpCode.SharpZipLib.Core;
|
using ICSharpCode.SharpZipLib.Core;
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
using LANCommander.PlaynitePlugin.Extensions;
|
using LANCommander.PlaynitePlugin.Extensions;
|
||||||
|
using LANCommander.PlaynitePlugin.Services;
|
||||||
using LANCommander.SDK;
|
using LANCommander.SDK;
|
||||||
using Playnite.SDK;
|
using Playnite.SDK;
|
||||||
using Playnite.SDK.Events;
|
using Playnite.SDK.Events;
|
||||||
|
@ -32,6 +33,7 @@ namespace LANCommander.PlaynitePlugin
|
||||||
internal LANCommanderSettingsViewModel Settings { get; set; }
|
internal LANCommanderSettingsViewModel Settings { get; set; }
|
||||||
internal LANCommanderClient LANCommander { get; set; }
|
internal LANCommanderClient LANCommander { get; set; }
|
||||||
internal PowerShellRuntime PowerShellRuntime { get; set; }
|
internal PowerShellRuntime PowerShellRuntime { get; set; }
|
||||||
|
internal GameSaveService GameSaveService { get; set; }
|
||||||
|
|
||||||
public override Guid Id { get; } = Guid.Parse("48e1bac7-e0a0-45d7-ba83-36f5e9e959fc");
|
public override Guid Id { get; } = Guid.Parse("48e1bac7-e0a0-45d7-ba83-36f5e9e959fc");
|
||||||
public override string Name => "LANCommander";
|
public override string Name => "LANCommander";
|
||||||
|
@ -56,6 +58,8 @@ namespace LANCommander.PlaynitePlugin
|
||||||
};
|
};
|
||||||
|
|
||||||
PowerShellRuntime = new PowerShellRuntime();
|
PowerShellRuntime = new PowerShellRuntime();
|
||||||
|
|
||||||
|
GameSaveService = new GameSaveService(LANCommander, PlayniteApi, PowerShellRuntime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnApplicationStarted(OnApplicationStartedEventArgs args)
|
public override void OnApplicationStarted(OnApplicationStartedEventArgs args)
|
||||||
|
@ -271,212 +275,14 @@ namespace LANCommander.PlaynitePlugin
|
||||||
|
|
||||||
public override void OnGameStarting(OnGameStartingEventArgs args)
|
public override void OnGameStarting(OnGameStartingEventArgs args)
|
||||||
{
|
{
|
||||||
DownloadSave(args.Game);
|
GameSaveService.DownloadSave(args.Game);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DownloadSave(Game game)
|
|
||||||
{
|
|
||||||
string tempFile = String.Empty;
|
|
||||||
|
|
||||||
if (game != null)
|
|
||||||
{
|
|
||||||
PlayniteApi.Dialogs.ActivateGlobalProgress(progress =>
|
|
||||||
{
|
|
||||||
progress.ProgressMaxValue = 100;
|
|
||||||
progress.CurrentProgressValue = 0;
|
|
||||||
|
|
||||||
var destination = LANCommander.DownloadLatestSave(Guid.Parse(game.GameId), (changed) =>
|
|
||||||
{
|
|
||||||
progress.CurrentProgressValue = changed.ProgressPercentage;
|
|
||||||
}, (complete) =>
|
|
||||||
{
|
|
||||||
progress.CurrentProgressValue = 100;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Lock the thread until download is done
|
|
||||||
while (progress.CurrentProgressValue != 100)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
tempFile = destination;
|
|
||||||
},
|
|
||||||
new GlobalProgressOptions("Downloading latest save...")
|
|
||||||
{
|
|
||||||
IsIndeterminate = false,
|
|
||||||
Cancelable = false
|
|
||||||
});
|
|
||||||
|
|
||||||
// Go into the archive and extract the files to the correct locations
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var tempLocation = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
|
||||||
|
|
||||||
Directory.CreateDirectory(tempLocation);
|
|
||||||
|
|
||||||
ExtractFilesFromZip(tempFile, tempLocation);
|
|
||||||
|
|
||||||
var deserializer = new DeserializerBuilder()
|
|
||||||
.WithNamingConvention(new PascalCaseNamingConvention())
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var manifestContents = File.ReadAllText(Path.Combine(tempLocation, "_manifest.yml"));
|
|
||||||
|
|
||||||
var manifest = deserializer.Deserialize<GameManifest>(manifestContents);
|
|
||||||
|
|
||||||
foreach (var savePath in manifest.SavePaths)
|
|
||||||
{
|
|
||||||
var pathTemp = Path.Combine(tempLocation, savePath.Id.ToString(), savePath.Path.Replace('/', '\\').Replace("{InstallDir}\\", ""));
|
|
||||||
var destination = savePath.Path.Replace('/', '\\').Replace("{InstallDir}", game.InstallDirectory);
|
|
||||||
|
|
||||||
if (File.Exists(pathTemp))
|
|
||||||
{
|
|
||||||
if (File.Exists(destination))
|
|
||||||
File.Delete(destination);
|
|
||||||
|
|
||||||
File.Move(pathTemp, destination);
|
|
||||||
}
|
|
||||||
else if (Directory.Exists(pathTemp))
|
|
||||||
{
|
|
||||||
// Better way to handle this? Maybe merge files?
|
|
||||||
Directory.Delete(destination, true);
|
|
||||||
Directory.Move(pathTemp, destination);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up temp files
|
|
||||||
Directory.Delete(tempLocation, true);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnGameStopped(OnGameStoppedEventArgs args)
|
public override void OnGameStopped(OnGameStoppedEventArgs args)
|
||||||
{
|
{
|
||||||
UploadSave(args.Game);
|
GameSaveService.UploadSave(args.Game);
|
||||||
}
|
|
||||||
|
|
||||||
private void UploadSave(Game game)
|
|
||||||
{
|
|
||||||
var manifestPath = Path.Combine(game.InstallDirectory, "_manifest.yml");
|
|
||||||
|
|
||||||
if (File.Exists(manifestPath))
|
|
||||||
{
|
|
||||||
var deserializer = new DeserializerBuilder()
|
|
||||||
.WithNamingConvention(new PascalCaseNamingConvention())
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var manifest = deserializer.Deserialize<GameManifest>(File.ReadAllText(manifestPath));
|
|
||||||
var temp = Path.GetTempFileName();
|
|
||||||
|
|
||||||
using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(temp)))
|
|
||||||
{
|
|
||||||
zipStream.SetLevel(5);
|
|
||||||
|
|
||||||
foreach (var savePath in manifest.SavePaths)
|
|
||||||
{
|
|
||||||
var localPath = savePath.Path.Replace('/', '\\').Replace("{InstallDir}", game.InstallDirectory);
|
|
||||||
|
|
||||||
if (Directory.Exists(localPath))
|
|
||||||
{
|
|
||||||
AddDirectoryToZip(zipStream, localPath);
|
|
||||||
}
|
|
||||||
else if (File.Exists(localPath))
|
|
||||||
{
|
|
||||||
var entry = new ZipEntry(Path.Combine(savePath.Id.ToString(), savePath.Path.Replace("{InstallDir}/", "")));
|
|
||||||
|
|
||||||
zipStream.PutNextEntry(entry);
|
|
||||||
|
|
||||||
byte[] buffer = File.ReadAllBytes(localPath);
|
|
||||||
|
|
||||||
zipStream.Write(buffer, 0, buffer.Length);
|
|
||||||
zipStream.CloseEntry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var manifestEntry = new ZipEntry("_manifest.yml");
|
|
||||||
|
|
||||||
zipStream.PutNextEntry(manifestEntry);
|
|
||||||
|
|
||||||
byte[] manifestBuffer = File.ReadAllBytes(manifestPath);
|
|
||||||
|
|
||||||
zipStream.Write(manifestBuffer, 0, manifestBuffer.Length);
|
|
||||||
zipStream.CloseEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
var save = LANCommander.UploadSave(game.GameId, File.ReadAllBytes(temp));
|
|
||||||
|
|
||||||
File.Delete(temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddDirectoryToZip(ZipOutputStream zipStream, string path)
|
|
||||||
{
|
|
||||||
foreach (var file in Directory.GetFiles(path))
|
|
||||||
{
|
|
||||||
var entry = new ZipEntry(Path.GetFileName(file));
|
|
||||||
|
|
||||||
zipStream.PutNextEntry(entry);
|
|
||||||
|
|
||||||
byte[] buffer = File.ReadAllBytes(file);
|
|
||||||
|
|
||||||
zipStream.Write(buffer, 0, buffer.Length);
|
|
||||||
|
|
||||||
zipStream.CloseEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var child in Directory.GetDirectories(path))
|
|
||||||
{
|
|
||||||
ZipEntry entry = new ZipEntry(Path.GetFileName(path));
|
|
||||||
|
|
||||||
zipStream.PutNextEntry(entry);
|
|
||||||
zipStream.CloseEntry();
|
|
||||||
|
|
||||||
AddDirectoryToZip(zipStream, child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExtractFilesFromZip(string zipPath, string destination)
|
|
||||||
{
|
|
||||||
ZipFile file = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
FileStream fs = File.OpenRead(zipPath);
|
|
||||||
|
|
||||||
file = new ZipFile(fs);
|
|
||||||
|
|
||||||
foreach (ZipEntry entry in file)
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<TopPanelItem> GetTopPanelItems()
|
public override IEnumerable<TopPanelItem> GetTopPanelItems()
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.RightsManagement;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
@ -20,6 +21,17 @@ namespace LANCommander.PlaynitePlugin
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
static extern bool Wow64RevertWow64FsRedirection(ref IntPtr ptr);
|
static extern bool Wow64RevertWow64FsRedirection(ref IntPtr ptr);
|
||||||
|
|
||||||
|
public void RunCommand(string command, bool asAdmin = false)
|
||||||
|
{
|
||||||
|
var tempScript = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".ps1");
|
||||||
|
|
||||||
|
File.WriteAllText(tempScript, command);
|
||||||
|
|
||||||
|
RunScript(tempScript, asAdmin);
|
||||||
|
|
||||||
|
File.Delete(tempScript);
|
||||||
|
}
|
||||||
|
|
||||||
public void RunScript(string path, bool asAdmin = false, string arguments = null)
|
public void RunScript(string path, bool asAdmin = false, string arguments = null)
|
||||||
{
|
{
|
||||||
var wow64Value = IntPtr.Zero;
|
var wow64Value = IntPtr.Zero;
|
||||||
|
@ -30,7 +42,8 @@ namespace LANCommander.PlaynitePlugin
|
||||||
|
|
||||||
process.StartInfo.FileName = "powershell.exe";
|
process.StartInfo.FileName = "powershell.exe";
|
||||||
process.StartInfo.Arguments = $@"-ExecutionPolicy Unrestricted -File ""{path}""";
|
process.StartInfo.Arguments = $@"-ExecutionPolicy Unrestricted -File ""{path}""";
|
||||||
process.StartInfo.UseShellExecute = true;
|
process.StartInfo.UseShellExecute = false;
|
||||||
|
process.StartInfo.RedirectStandardOutput = true;
|
||||||
|
|
||||||
if (arguments != null)
|
if (arguments != null)
|
||||||
process.StartInfo.Arguments += " " + arguments;
|
process.StartInfo.Arguments += " " + arguments;
|
||||||
|
|
275
LANCommander.Playnite.Extension/Services/GameSaveService.cs
Normal file
275
LANCommander.Playnite.Extension/Services/GameSaveService.cs
Normal file
|
@ -0,0 +1,275 @@
|
||||||
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
|
using LANCommander.SDK;
|
||||||
|
using Playnite.SDK.Models;
|
||||||
|
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;
|
||||||
|
|
||||||
|
namespace LANCommander.PlaynitePlugin.Services
|
||||||
|
{
|
||||||
|
internal class GameSaveService
|
||||||
|
{
|
||||||
|
private readonly LANCommanderClient LANCommander;
|
||||||
|
private readonly IPlayniteAPI PlayniteApi;
|
||||||
|
private readonly PowerShellRuntime PowerShellRuntime;
|
||||||
|
|
||||||
|
internal GameSaveService(LANCommanderClient lanCommander, IPlayniteAPI playniteApi, PowerShellRuntime powerShellRuntime) {
|
||||||
|
LANCommander = lanCommander;
|
||||||
|
PlayniteApi = playniteApi;
|
||||||
|
PowerShellRuntime = powerShellRuntime;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void DownloadSave(Game game)
|
||||||
|
{
|
||||||
|
string tempFile = String.Empty;
|
||||||
|
|
||||||
|
if (game != null)
|
||||||
|
{
|
||||||
|
PlayniteApi.Dialogs.ActivateGlobalProgress(progress =>
|
||||||
|
{
|
||||||
|
progress.ProgressMaxValue = 100;
|
||||||
|
progress.CurrentProgressValue = 0;
|
||||||
|
|
||||||
|
var destination = LANCommander.DownloadLatestSave(Guid.Parse(game.GameId), (changed) =>
|
||||||
|
{
|
||||||
|
progress.CurrentProgressValue = changed.ProgressPercentage;
|
||||||
|
}, (complete) =>
|
||||||
|
{
|
||||||
|
progress.CurrentProgressValue = 100;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Lock the thread until download is done
|
||||||
|
while (progress.CurrentProgressValue != 100)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tempFile = destination;
|
||||||
|
},
|
||||||
|
new GlobalProgressOptions("Downloading latest save...")
|
||||||
|
{
|
||||||
|
IsIndeterminate = false,
|
||||||
|
Cancelable = false
|
||||||
|
});
|
||||||
|
|
||||||
|
// Go into the archive and extract the files to the correct locations
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var tempLocation = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||||
|
|
||||||
|
Directory.CreateDirectory(tempLocation);
|
||||||
|
|
||||||
|
ExtractFilesFromZip(tempFile, tempLocation);
|
||||||
|
|
||||||
|
var deserializer = new DeserializerBuilder()
|
||||||
|
.WithNamingConvention(new PascalCaseNamingConvention())
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var manifestContents = File.ReadAllText(Path.Combine(tempLocation, "_manifest.yml"));
|
||||||
|
|
||||||
|
var manifest = deserializer.Deserialize<GameManifest>(manifestContents);
|
||||||
|
|
||||||
|
#region Move files
|
||||||
|
foreach (var savePath in manifest.SavePaths)
|
||||||
|
{
|
||||||
|
var pathTemp = Path.Combine(tempLocation, savePath.Id.ToString(), savePath.Path.Replace('/', '\\').Replace("{InstallDir}\\", ""));
|
||||||
|
var destination = savePath.Path.Replace('/', '\\').Replace("{InstallDir}", game.InstallDirectory);
|
||||||
|
|
||||||
|
if (File.Exists(pathTemp))
|
||||||
|
{
|
||||||
|
if (File.Exists(destination))
|
||||||
|
File.Delete(destination);
|
||||||
|
|
||||||
|
File.Move(pathTemp, destination);
|
||||||
|
}
|
||||||
|
else if (Directory.Exists(pathTemp))
|
||||||
|
{
|
||||||
|
// Better way to handle this? Maybe merge files?
|
||||||
|
Directory.Delete(destination, true);
|
||||||
|
Directory.Move(pathTemp, destination);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Handle registry importing
|
||||||
|
var registryImportFilePath = Path.Combine(tempLocation, "_registry.reg");
|
||||||
|
|
||||||
|
if (File.Exists(registryImportFilePath))
|
||||||
|
{
|
||||||
|
var registryImportFileContents = File.ReadAllText(registryImportFilePath);
|
||||||
|
|
||||||
|
PowerShellRuntime.RunCommand($"regedit.exe /s \"{registryImportFilePath}\"", registryImportFileContents.Contains("HKEY_LOCAL_MACHINE"));
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// Clean up temp files
|
||||||
|
Directory.Delete(tempLocation, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void UploadSave(Game game)
|
||||||
|
{
|
||||||
|
var manifestPath = Path.Combine(game.InstallDirectory, "_manifest.yml");
|
||||||
|
|
||||||
|
if (File.Exists(manifestPath))
|
||||||
|
{
|
||||||
|
var deserializer = new DeserializerBuilder()
|
||||||
|
.WithNamingConvention(new PascalCaseNamingConvention())
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var manifest = deserializer.Deserialize<GameManifest>(File.ReadAllText(manifestPath));
|
||||||
|
var temp = Path.GetTempFileName();
|
||||||
|
|
||||||
|
using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(temp)))
|
||||||
|
{
|
||||||
|
zipStream.SetLevel(5);
|
||||||
|
|
||||||
|
#region Add files from defined paths
|
||||||
|
foreach (var savePath in manifest.SavePaths.Where(sp => sp.Type == "File"))
|
||||||
|
{
|
||||||
|
var localPath = savePath.Path.Replace('/', '\\').Replace("{InstallDir}", game.InstallDirectory);
|
||||||
|
|
||||||
|
if (Directory.Exists(localPath))
|
||||||
|
{
|
||||||
|
AddDirectoryToZip(zipStream, localPath);
|
||||||
|
}
|
||||||
|
else if (File.Exists(localPath))
|
||||||
|
{
|
||||||
|
var entry = new ZipEntry(Path.Combine(savePath.Id.ToString(), savePath.Path.Replace("{InstallDir}/", "")));
|
||||||
|
|
||||||
|
zipStream.PutNextEntry(entry);
|
||||||
|
|
||||||
|
byte[] buffer = File.ReadAllBytes(localPath);
|
||||||
|
|
||||||
|
zipStream.Write(buffer, 0, buffer.Length);
|
||||||
|
zipStream.CloseEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Export registry keys
|
||||||
|
List<string> tempRegFiles = new List<string>();
|
||||||
|
|
||||||
|
var exportCommand = new StringBuilder();
|
||||||
|
|
||||||
|
foreach (var savePath in manifest.SavePaths.Where(sp => sp.Type == "Registry"))
|
||||||
|
{
|
||||||
|
var tempRegFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".reg");
|
||||||
|
|
||||||
|
exportCommand.AppendLine($"reg.exe export \"{savePath.Path.Replace(":\\", "\\")}\" \"{tempRegFile}\"");
|
||||||
|
tempRegFiles.Add(tempRegFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
PowerShellRuntime.RunCommand(exportCommand.ToString());
|
||||||
|
|
||||||
|
var exportFile = new StringBuilder();
|
||||||
|
|
||||||
|
foreach (var tempRegFile in tempRegFiles)
|
||||||
|
{
|
||||||
|
exportFile.AppendLine(File.ReadAllText(tempRegFile));
|
||||||
|
File.Delete(tempRegFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
zipStream.PutNextEntry(new ZipEntry("_registry.reg"));
|
||||||
|
|
||||||
|
byte[] regBuffer = Encoding.UTF8.GetBytes(exportFile.ToString());
|
||||||
|
|
||||||
|
zipStream.Write(regBuffer, 0, regBuffer.Length);
|
||||||
|
zipStream.CloseEntry();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var manifestEntry = new ZipEntry("_manifest.yml");
|
||||||
|
|
||||||
|
zipStream.PutNextEntry(manifestEntry);
|
||||||
|
|
||||||
|
byte[] manifestBuffer = File.ReadAllBytes(manifestPath);
|
||||||
|
|
||||||
|
zipStream.Write(manifestBuffer, 0, manifestBuffer.Length);
|
||||||
|
zipStream.CloseEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
var save = LANCommander.UploadSave(game.GameId, File.ReadAllBytes(temp));
|
||||||
|
|
||||||
|
File.Delete(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddDirectoryToZip(ZipOutputStream zipStream, string path)
|
||||||
|
{
|
||||||
|
foreach (var file in Directory.GetFiles(path))
|
||||||
|
{
|
||||||
|
var entry = new ZipEntry(Path.GetFileName(file));
|
||||||
|
|
||||||
|
zipStream.PutNextEntry(entry);
|
||||||
|
|
||||||
|
byte[] buffer = File.ReadAllBytes(file);
|
||||||
|
|
||||||
|
zipStream.Write(buffer, 0, buffer.Length);
|
||||||
|
|
||||||
|
zipStream.CloseEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var child in Directory.GetDirectories(path))
|
||||||
|
{
|
||||||
|
ZipEntry entry = new ZipEntry(Path.GetFileName(path));
|
||||||
|
|
||||||
|
zipStream.PutNextEntry(entry);
|
||||||
|
zipStream.CloseEntry();
|
||||||
|
|
||||||
|
AddDirectoryToZip(zipStream, child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExtractFilesFromZip(string zipPath, string destination)
|
||||||
|
{
|
||||||
|
ZipFile file = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileStream fs = File.OpenRead(zipPath);
|
||||||
|
|
||||||
|
file = new ZipFile(fs);
|
||||||
|
|
||||||
|
foreach (ZipEntry entry in file)
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue