2023-01-07 04:12:03 +00:00
|
|
|
|
using Playnite.SDK;
|
|
|
|
|
using Playnite.SDK.Models;
|
|
|
|
|
using Playnite.SDK.Plugins;
|
2023-01-15 10:29:47 +00:00
|
|
|
|
using LANCommander.SDK.Enums;
|
2023-01-07 04:12:03 +00:00
|
|
|
|
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;
|
2023-01-14 21:09:45 +00:00
|
|
|
|
using YamlDotNet.Serialization;
|
|
|
|
|
using YamlDotNet.Serialization.NamingConventions;
|
2023-01-15 10:29:47 +00:00
|
|
|
|
using LANCommander.SDK.Models;
|
2023-01-17 05:45:46 +00:00
|
|
|
|
using System.Collections.ObjectModel;
|
2023-01-07 04:12:03 +00:00
|
|
|
|
|
2023-01-08 18:09:57 +00:00
|
|
|
|
namespace LANCommander.PlaynitePlugin
|
2023-01-07 04:12:03 +00:00
|
|
|
|
{
|
|
|
|
|
public class LANCommanderInstallController : InstallController
|
|
|
|
|
{
|
2023-01-14 21:15:31 +00:00
|
|
|
|
private LANCommanderLibraryPlugin Plugin;
|
2023-01-15 07:10:36 +00:00
|
|
|
|
private PowerShellRuntime PowerShellRuntime;
|
2023-01-15 10:29:47 +00:00
|
|
|
|
private Playnite.SDK.Models.Game PlayniteGame;
|
2023-01-07 04:12:03 +00:00
|
|
|
|
|
2023-01-15 10:29:47 +00:00
|
|
|
|
public LANCommanderInstallController(LANCommanderLibraryPlugin plugin, Playnite.SDK.Models.Game game) : base(game)
|
2023-01-07 04:12:03 +00:00
|
|
|
|
{
|
|
|
|
|
Name = "Install using LANCommander";
|
|
|
|
|
Plugin = plugin;
|
2023-01-15 07:10:36 +00:00
|
|
|
|
PlayniteGame = game;
|
|
|
|
|
PowerShellRuntime = new PowerShellRuntime();
|
2023-01-07 04:12:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Install(InstallActionArgs args)
|
|
|
|
|
{
|
|
|
|
|
var gameId = Guid.Parse(Game.GameId);
|
|
|
|
|
|
|
|
|
|
var game = Plugin.LANCommander.GetGame(gameId);
|
2023-01-17 05:45:46 +00:00
|
|
|
|
var manifest = Plugin.LANCommander.GetGameManifest(gameId);
|
2023-01-07 04:12:03 +00:00
|
|
|
|
|
|
|
|
|
var tempFile = Download(game);
|
|
|
|
|
|
2023-01-07 04:39:56 +00:00
|
|
|
|
var installDirectory = Extract(game, tempFile);
|
2023-01-15 07:10:36 +00:00
|
|
|
|
|
2023-01-07 04:39:56 +00:00
|
|
|
|
var installInfo = new GameInstallationData()
|
|
|
|
|
{
|
|
|
|
|
InstallDirectory = installDirectory
|
|
|
|
|
};
|
|
|
|
|
|
2023-01-15 07:10:36 +00:00
|
|
|
|
PlayniteGame.InstallDirectory = installDirectory;
|
|
|
|
|
|
2023-01-17 05:45:46 +00:00
|
|
|
|
WriteManifest(manifest, installDirectory);
|
2023-01-14 21:09:45 +00:00
|
|
|
|
|
2023-01-15 10:29:47 +00:00
|
|
|
|
SaveScript(game, installDirectory, ScriptType.Install);
|
|
|
|
|
SaveScript(game, installDirectory, ScriptType.Uninstall);
|
|
|
|
|
SaveScript(game, installDirectory, ScriptType.NameChange);
|
|
|
|
|
SaveScript(game, installDirectory, ScriptType.KeyChange);
|
|
|
|
|
|
2023-01-15 07:19:03 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
2023-01-15 10:29:47 +00:00
|
|
|
|
PowerShellRuntime.RunScript(PlayniteGame, ScriptType.Install);
|
2023-01-20 02:03:16 +00:00
|
|
|
|
PowerShellRuntime.RunScript(PlayniteGame, ScriptType.NameChange, Plugin.Settings.PlayerName);
|
2023-01-28 23:18:41 +00:00
|
|
|
|
|
|
|
|
|
var key = Plugin.LANCommander.GetAllocatedKey(game.Id);
|
|
|
|
|
|
|
|
|
|
PowerShellRuntime.RunScript(PlayniteGame, ScriptType.KeyChange, $"\"{key}\"");
|
2023-01-15 07:19:03 +00:00
|
|
|
|
}
|
|
|
|
|
catch { }
|
2023-01-15 07:10:36 +00:00
|
|
|
|
|
2023-01-17 05:45:46 +00:00
|
|
|
|
Plugin.UpdateGame(manifest, gameId);
|
2023-01-07 20:32:52 +00:00
|
|
|
|
|
2023-01-17 05:45:46 +00:00
|
|
|
|
InvokeOnInstalled(new GameInstalledEventArgs(installInfo));
|
2023-01-07 04:12:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string Download(LANCommander.SDK.Models.Game game)
|
|
|
|
|
{
|
|
|
|
|
string tempFile = String.Empty;
|
|
|
|
|
|
2023-01-14 21:09:45 +00:00
|
|
|
|
if (game != null)
|
2023-01-07 04:12:03 +00:00
|
|
|
|
{
|
2023-01-07 04:39:56 +00:00
|
|
|
|
Plugin.PlayniteApi.Dialogs.ActivateGlobalProgress(progress =>
|
2023-01-07 04:12:03 +00:00
|
|
|
|
{
|
|
|
|
|
progress.ProgressMaxValue = 100;
|
|
|
|
|
progress.CurrentProgressValue = 0;
|
|
|
|
|
|
2023-01-14 21:09:45 +00:00
|
|
|
|
var destination = Plugin.LANCommander.DownloadGame(game.Id, (changed) =>
|
2023-01-07 04:12:03 +00:00
|
|
|
|
{
|
|
|
|
|
progress.CurrentProgressValue = changed.ProgressPercentage;
|
|
|
|
|
}, (complete) =>
|
|
|
|
|
{
|
|
|
|
|
progress.CurrentProgressValue = 100;
|
|
|
|
|
});
|
|
|
|
|
|
2023-01-07 04:39:56 +00:00
|
|
|
|
// Lock the thread until download is done
|
2023-01-07 04:12:03 +00:00
|
|
|
|
while (progress.CurrentProgressValue != 100)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tempFile = destination;
|
|
|
|
|
},
|
2023-01-07 04:39:56 +00:00
|
|
|
|
new GlobalProgressOptions($"Downloading {game.Title}...")
|
2023-01-07 04:12:03 +00:00
|
|
|
|
{
|
|
|
|
|
IsIndeterminate = false,
|
|
|
|
|
Cancelable = false,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return tempFile;
|
|
|
|
|
}
|
|
|
|
|
else
|
2023-01-14 21:09:45 +00:00
|
|
|
|
throw new Exception("Game failed to download!");
|
2023-01-07 04:12:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-01-07 04:39:56 +00:00
|
|
|
|
private string Extract(LANCommander.SDK.Models.Game game, string archivePath)
|
2023-01-07 04:12:03 +00:00
|
|
|
|
{
|
2023-01-12 02:48:39 +00:00
|
|
|
|
var destination = Path.Combine(Plugin.Settings.InstallDirectory, game.Title.SanitizeFilename());
|
2023-01-07 04:12:03 +00:00
|
|
|
|
|
2023-01-07 04:39:56 +00:00
|
|
|
|
Plugin.PlayniteApi.Dialogs.ActivateGlobalProgress(progress =>
|
2023-01-07 04:12:03 +00:00
|
|
|
|
{
|
2023-01-07 04:39:56 +00:00
|
|
|
|
ZipFile file = null;
|
2023-01-07 04:12:03 +00:00
|
|
|
|
|
2023-01-07 04:39:56 +00:00
|
|
|
|
try
|
2023-01-07 04:12:03 +00:00
|
|
|
|
{
|
2023-01-07 04:39:56 +00:00
|
|
|
|
FileStream fs = File.OpenRead(archivePath);
|
2023-01-07 04:12:03 +00:00
|
|
|
|
|
2023-01-07 04:39:56 +00:00
|
|
|
|
file = new ZipFile(fs);
|
2023-01-07 04:12:03 +00:00
|
|
|
|
|
2023-01-07 04:39:56 +00:00
|
|
|
|
progress.ProgressMaxValue = file.Count;
|
2023-01-07 04:12:03 +00:00
|
|
|
|
|
2023-01-07 04:39:56 +00:00
|
|
|
|
foreach (ZipEntry entry in file)
|
2023-01-07 04:12:03 +00:00
|
|
|
|
{
|
2023-01-07 04:39:56 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
progress.CurrentProgressValue = entry.ZipFileIndex;
|
2023-01-07 04:12:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-07 04:39:56 +00:00
|
|
|
|
finally
|
2023-01-07 04:12:03 +00:00
|
|
|
|
{
|
2023-01-07 04:39:56 +00:00
|
|
|
|
if (file != null)
|
|
|
|
|
{
|
|
|
|
|
file.IsStreamOwner = true;
|
|
|
|
|
file.Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
File.Delete(archivePath);
|
2023-01-07 04:12:03 +00:00
|
|
|
|
}
|
2023-01-07 04:39:56 +00:00
|
|
|
|
},
|
|
|
|
|
new GlobalProgressOptions($"Extracting {game.Title}...")
|
|
|
|
|
{
|
|
|
|
|
IsIndeterminate = false,
|
|
|
|
|
Cancelable = false,
|
|
|
|
|
});
|
2023-01-07 04:12:03 +00:00
|
|
|
|
|
2023-01-07 04:39:56 +00:00
|
|
|
|
return destination;
|
2023-01-07 04:12:03 +00:00
|
|
|
|
}
|
2023-01-14 21:09:45 +00:00
|
|
|
|
|
2023-01-17 05:45:46 +00:00
|
|
|
|
private void WriteManifest(SDK.GameManifest manifest, string installDirectory)
|
2023-01-14 21:09:45 +00:00
|
|
|
|
{
|
|
|
|
|
var serializer = new SerializerBuilder()
|
|
|
|
|
.WithNamingConvention(PascalCaseNamingConvention.Instance)
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
var yaml = serializer.Serialize(manifest);
|
|
|
|
|
|
2023-01-17 05:45:46 +00:00
|
|
|
|
File.WriteAllText(Path.Combine(installDirectory, "_manifest.yml"), yaml);
|
2023-01-14 21:09:45 +00:00
|
|
|
|
}
|
2023-01-15 10:29:47 +00:00
|
|
|
|
|
|
|
|
|
private void SaveScript(LANCommander.SDK.Models.Game game, string installationDirectory, ScriptType type)
|
|
|
|
|
{
|
|
|
|
|
var script = game.Scripts.FirstOrDefault(s => s.Type == type);
|
|
|
|
|
|
|
|
|
|
if (script == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (script.RequiresAdmin)
|
|
|
|
|
script.Contents = "# Requires Admin" + "\r\n\r\n" + script.Contents;
|
|
|
|
|
|
2023-01-15 10:56:56 +00:00
|
|
|
|
var filename = PowerShellRuntime.GetScriptFilePath(PlayniteGame, type);
|
2023-01-15 10:29:47 +00:00
|
|
|
|
|
|
|
|
|
if (File.Exists(filename))
|
|
|
|
|
File.Delete(filename);
|
|
|
|
|
|
|
|
|
|
File.WriteAllText(filename, script.Contents);
|
|
|
|
|
}
|
2023-01-07 04:12:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|