Switched the library importing in the launcher to work based on a queue. As a new game is added to the queue, it should find any related data and also add it to the queue. This should result in an easier to maintain importer while reducing the load on the launcher's DAL. This may result in more RAM usage while importing. Local manifests have also been refactored to match manifests in import/export LCX files, removing the old manifest format. This is a large breaking change that will probably break existing game installations. A migration will probably have to be created.
991 lines
43 KiB
C#
991 lines
43 KiB
C#
using LANCommander.SDK.Extensions;
|
|
using LANCommander.SDK.Helpers;
|
|
using LANCommander.SDK.Models;
|
|
using LANCommander.SDK.PowerShell;
|
|
using Microsoft.Extensions.Logging;
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using LANCommander.SDK.Abstractions;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
namespace LANCommander.SDK.Services
|
|
{
|
|
public class ScriptClient(
|
|
ILogger<ScriptClient> logger,
|
|
IServiceProvider serviceProvider,
|
|
ISettingsProvider settingsProvider,
|
|
PowerShellScriptFactory powerShellScriptFactory,
|
|
IConnectionClient connectionClient)
|
|
{
|
|
public bool Debug { get; set; }
|
|
|
|
#region Authentication Scripts
|
|
public async Task RunUserLoginScript(Script loginScript, User user)
|
|
{
|
|
try
|
|
{
|
|
using (var op = logger.BeginOperation("Executing user login script"))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.UserLogin);
|
|
|
|
script.AddVariable("User", user);
|
|
|
|
script.UseInline(loginScript.Contents);
|
|
|
|
try
|
|
{
|
|
op
|
|
.Enrich("UserId", user.Id)
|
|
.Enrich("Username", user.UserName)
|
|
.Enrich("ScriptId", loginScript.Id)
|
|
.Enrich("ScriptName", loginScript.Name);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
await script.ExecuteAsync<int>();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not execute user login script");
|
|
}
|
|
}
|
|
|
|
public async Task RunUserRegistrationScript(Script registrationScript, User user)
|
|
{
|
|
try
|
|
{
|
|
using (var op = logger.BeginOperation("Executing user registration script"))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.UserRegistration);
|
|
|
|
script.AddVariable("User", user);
|
|
|
|
script.UseInline(registrationScript.Contents);
|
|
|
|
try
|
|
{
|
|
op
|
|
.Enrich("UserId", user.Id)
|
|
.Enrich("Username", user.UserName)
|
|
.Enrich("ScriptId", registrationScript.Id)
|
|
.Enrich("ScriptName", registrationScript.Name);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
await script.ExecuteAsync<int>();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not execute user registration script");
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Redistributables
|
|
public async Task<bool> RunDetectInstallScriptAsync(string installDirectory, Guid gameId, Guid redistributableId)
|
|
{
|
|
bool result = default;
|
|
|
|
var gameManifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Game>(installDirectory, gameId);
|
|
var redistributableManifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Redistributable>(installDirectory, redistributableId);
|
|
|
|
var path = ScriptHelper.GetScriptFilePath(installDirectory, redistributableId, Enums.ScriptType.DetectInstall);
|
|
|
|
try
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
using (var op = logger.BeginOperation("Executing install detection script"))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.DetectInstall);
|
|
|
|
script.AddVariable("InstallDirectory", installDirectory);
|
|
script.AddVariable("GameManifest", gameManifest);
|
|
script.AddVariable("RedistributableManifest", redistributableManifest);
|
|
script.AddVariable("DefaultInstallDirectory", settingsProvider.CurrentValue.Games.InstallDirectories.FirstOrDefault());
|
|
script.AddVariable("ServerAddress", connectionClient.GetServerAddress());
|
|
|
|
try
|
|
{
|
|
op.Enrich("InstallDirectory", installDirectory)
|
|
.Enrich("GameManifestPath", ManifestHelper.GetPath(installDirectory, gameId))
|
|
.Enrich("RedistributableManifestPath", ManifestHelper.GetPath(installDirectory, redistributableId))
|
|
.Enrich("ScriptPath", path)
|
|
.Enrich("GameTitle", gameManifest.Title)
|
|
.Enrich("GameId", gameManifest.Id)
|
|
.Enrich("RedistributableName", redistributableManifest.Name)
|
|
.Enrich("RedistributableId", redistributableManifest.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
if (gameManifest.CustomFields != null && gameManifest.CustomFields.Any())
|
|
{
|
|
foreach (var customField in gameManifest.CustomFields)
|
|
{
|
|
script.AddVariable(customField.Name, customField.Value);
|
|
}
|
|
}
|
|
|
|
script.UseWorkingDirectory(Path.Combine(GameClient.GetMetadataDirectoryPath(installDirectory, redistributableId)));
|
|
script.UseFile(path);
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
var handled = await RunScriptExternallyAsync(script);
|
|
|
|
if (!handled)
|
|
{
|
|
using (var timeoutCancellationTokenSource = new CancellationTokenSource())
|
|
{
|
|
var task = script.ExecuteAsync<bool>();
|
|
|
|
var completedTask = await Task.WhenAny(task, Task.Delay(TimeSpan.FromSeconds(10), timeoutCancellationTokenSource.Token));
|
|
|
|
if (completedTask == task)
|
|
{
|
|
await timeoutCancellationTokenSource.CancelAsync();
|
|
return await task;
|
|
} else {
|
|
throw new TimeoutException("The operation has timed out.");
|
|
}
|
|
}
|
|
}
|
|
|
|
result = await script.ExecuteAsync<bool>();
|
|
|
|
op.Complete();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Ran into an unexpected error when attempting to run a Detect Install script");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> RunInstallScriptAsync(string installDirectory, Guid gameId, Guid redistributableId)
|
|
{
|
|
int result = default;
|
|
|
|
var gameManifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Game>(installDirectory, gameId);
|
|
var redistributableManifest = await ManifestHelper.ReadAsync<Redistributable>(installDirectory, redistributableId);
|
|
|
|
var path = ScriptHelper.GetScriptFilePath(installDirectory, redistributableId, Enums.ScriptType.Install);
|
|
|
|
try
|
|
{
|
|
if (Path.Exists(path))
|
|
{
|
|
using (var op = logger.BeginOperation("Executing install detection script"))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.Install);
|
|
|
|
script.AddVariable("InstallDirectory", installDirectory);
|
|
script.AddVariable("GameManifest", gameManifest);
|
|
script.AddVariable("RedistributableManifest", redistributableManifest);
|
|
script.AddVariable("DefaultInstallDirectory", settingsProvider.CurrentValue.Games.InstallDirectories.FirstOrDefault());
|
|
script.AddVariable("ServerAddress", connectionClient.GetServerAddress());
|
|
|
|
try
|
|
{
|
|
op
|
|
.Enrich("InstallDirectory", installDirectory)
|
|
.Enrich("GameManifestPath", ManifestHelper.GetPath(installDirectory, gameId))
|
|
.Enrich("RedistributableManifestPath", ManifestHelper.GetPath(installDirectory, redistributableId))
|
|
.Enrich("ScriptPath", path)
|
|
.Enrich("GameTitle", gameManifest.Title)
|
|
.Enrich("GameId", gameManifest.Id)
|
|
.Enrich("RedistributableName", redistributableManifest.Name)
|
|
.Enrich("RedistributableId", redistributableManifest.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
if (gameManifest.CustomFields != null && gameManifest.CustomFields.Any())
|
|
{
|
|
foreach (var customField in gameManifest.CustomFields)
|
|
{
|
|
script.AddVariable(customField.Name, customField.Value);
|
|
}
|
|
}
|
|
|
|
var extractionPath = Path.Combine(GameClient.GetMetadataDirectoryPath(installDirectory, redistributableId), "Files");
|
|
|
|
script.UseWorkingDirectory(extractionPath);
|
|
script.UseFile(path);
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
var handled = await RunScriptExternallyAsync(script);
|
|
|
|
if (!handled)
|
|
result = await script.ExecuteAsync<int>();
|
|
|
|
op.Complete();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Ran into an unexpected error when attempting to run a Detect Install script");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> RunBeforeStartScriptAsync(string installDirectory, Guid gameId, Guid redistributableId)
|
|
{
|
|
int result = default;
|
|
|
|
try
|
|
{
|
|
var gameManifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Game>(installDirectory, gameId);
|
|
var redistributableManifest = await ManifestHelper.ReadAsync<Redistributable>(installDirectory, redistributableId);
|
|
|
|
var path = ScriptHelper.GetScriptFilePath(installDirectory, redistributableId, Enums.ScriptType.BeforeStart);
|
|
|
|
using (var op = logger.BeginOperation("Executing before start script"))
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.BeforeStart);
|
|
var playerAlias = await GameClient.GetPlayerAliasAsync(installDirectory, gameId);
|
|
|
|
script.AddVariable("InstallDirectory", installDirectory);
|
|
script.AddVariable("GameManifest", gameManifest);
|
|
script.AddVariable("RedistributableManifest", redistributableManifest);
|
|
script.AddVariable("DefaultInstallDirectory", settingsProvider.CurrentValue.Games.InstallDirectories.FirstOrDefault());
|
|
script.AddVariable("ServerAddress", connectionClient.GetServerAddress());
|
|
script.AddVariable("PlayerAlias", playerAlias);
|
|
|
|
try
|
|
{
|
|
op
|
|
.Enrich("InstallDirectory", installDirectory)
|
|
.Enrich("GameManifestPath", ManifestHelper.GetPath(installDirectory, gameId))
|
|
.Enrich("RedistributableManifestPath", ManifestHelper.GetPath(installDirectory, redistributableId))
|
|
.Enrich("ScriptPath", path)
|
|
.Enrich("PlayerAlias", playerAlias)
|
|
.Enrich("GameTitle", gameManifest.Title)
|
|
.Enrich("GameId", gameManifest.Id)
|
|
.Enrich("RedistributableName", redistributableManifest.Name)
|
|
.Enrich("RedistributableId", redistributableManifest.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
if (gameManifest.CustomFields != null && gameManifest.CustomFields.Any())
|
|
{
|
|
foreach (var customField in gameManifest.CustomFields)
|
|
{
|
|
script.AddVariable(customField.Name, customField.Value);
|
|
}
|
|
}
|
|
|
|
var extractionPath = Path.Combine(GameClient.GetMetadataDirectoryPath(installDirectory, redistributableId), "Files");
|
|
|
|
script.UseWorkingDirectory(extractionPath);
|
|
script.UseFile(path);
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
var handled = await RunScriptExternallyAsync(script);
|
|
|
|
if (!handled)
|
|
result = await script.ExecuteAsync<int>();
|
|
}
|
|
else
|
|
{
|
|
logger?.LogTrace("No before start script found");
|
|
}
|
|
|
|
op.Complete();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Ran into an unexpected error when attempting to run a Before Start script");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> RunAfterStopScriptAsync(string installDirectory, Guid gameId, Guid redistributableId)
|
|
{
|
|
int result = default;
|
|
|
|
try
|
|
{
|
|
var gameManifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Game>(installDirectory, gameId);
|
|
var redistributableManifest = await ManifestHelper.ReadAsync<Redistributable>(installDirectory, redistributableId);
|
|
|
|
var path = ScriptHelper.GetScriptFilePath(installDirectory, redistributableId, Enums.ScriptType.AfterStop);
|
|
|
|
using (var op = logger.BeginOperation("Executing after stop script"))
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.AfterStop);
|
|
|
|
script.AddVariable("InstallDirectory", installDirectory);
|
|
script.AddVariable("GameManifest", gameManifest);
|
|
script.AddVariable("RedistributableManifest", redistributableManifest);
|
|
script.AddVariable("DefaultInstallDirectory", settingsProvider.CurrentValue.Games.InstallDirectories.FirstOrDefault());
|
|
script.AddVariable("ServerAddress", connectionClient.GetServerAddress());
|
|
script.AddVariable("PlayerAlias", await GameClient.GetPlayerAliasAsync(installDirectory, gameId));
|
|
|
|
try
|
|
{
|
|
op
|
|
.Enrich("InstallDirectory", installDirectory)
|
|
.Enrich("GameManifestPath", ManifestHelper.GetPath(installDirectory, gameId))
|
|
.Enrich("RedistributableManifestPath",
|
|
ManifestHelper.GetPath(installDirectory, redistributableId))
|
|
.Enrich("ScriptPath", path)
|
|
.Enrich("GameTitle", gameManifest.Title)
|
|
.Enrich("GameId", gameManifest.Id)
|
|
.Enrich("RedistributableName", redistributableManifest.Name)
|
|
.Enrich("RedistributableId", redistributableManifest.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
if (gameManifest.CustomFields != null && gameManifest.CustomFields.Any())
|
|
{
|
|
foreach (var customField in gameManifest.CustomFields)
|
|
{
|
|
script.AddVariable(customField.Name, customField.Value);
|
|
}
|
|
}
|
|
|
|
var extractionPath = Path.Combine(GameClient.GetMetadataDirectoryPath(installDirectory, redistributableId), "Files");
|
|
|
|
script.UseWorkingDirectory(extractionPath);
|
|
script.UseFile(path);
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
var handled = await RunScriptExternallyAsync(script);
|
|
|
|
if (!handled)
|
|
result = await script.ExecuteAsync<int>();
|
|
}
|
|
else
|
|
{
|
|
logger?.LogTrace("No after stop script found");
|
|
}
|
|
|
|
op.Complete();
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Ran into an unexpected error when attempting to run an After Stop script");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> RunNameChangeScriptAsync(string installDirectory, Guid gameId, Guid redistributableId, string newName)
|
|
{
|
|
int result = default;
|
|
|
|
try
|
|
{
|
|
var gameManifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Game>(installDirectory, gameId);
|
|
var redistributableManifest = await ManifestHelper.ReadAsync<Redistributable>(installDirectory, redistributableId);
|
|
|
|
var path = ScriptHelper.GetScriptFilePath(installDirectory, redistributableId, Enums.ScriptType.NameChange);
|
|
|
|
using (var op = logger.BeginOperation("Executing name change script"))
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
var oldName = await GameClient.GetPlayerAliasAsync(installDirectory, gameId);
|
|
|
|
if (oldName == newName)
|
|
oldName = string.Empty;
|
|
|
|
if (!string.IsNullOrWhiteSpace(oldName))
|
|
logger?.LogTrace("Old Name: {OldName}", oldName);
|
|
|
|
logger?.LogTrace("New Name: {NewName}", newName);
|
|
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.NameChange);
|
|
|
|
script.AddVariable("InstallDirectory", installDirectory);
|
|
script.AddVariable("GameManifest", gameManifest);
|
|
script.AddVariable("RedistributableManifest", redistributableManifest);
|
|
script.AddVariable("DefaultInstallDirectory", settingsProvider.CurrentValue.Games.InstallDirectories.FirstOrDefault());
|
|
script.AddVariable("ServerAddress", connectionClient.GetServerAddress());
|
|
script.AddVariable("OldPlayerAlias", oldName);
|
|
script.AddVariable("NewPlayerAlias", newName);
|
|
|
|
try
|
|
{
|
|
op.Enrich("InstallDirectory", installDirectory)
|
|
.Enrich("GameManifestPath", ManifestHelper.GetPath(installDirectory, gameId))
|
|
.Enrich("RedistributableManifestPath", ManifestHelper.GetPath(installDirectory, redistributableId))
|
|
.Enrich("ScriptPath", path)
|
|
.Enrich("OldPlayerAlias", oldName)
|
|
.Enrich("NewPlayerAlias", newName)
|
|
.Enrich("GameTitle", gameManifest.Title)
|
|
.Enrich("GameId", gameManifest.Id)
|
|
.Enrich("RedistributableName", redistributableManifest.Name)
|
|
.Enrich("RedistributableId", redistributableManifest.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
if (gameManifest.CustomFields != null && gameManifest.CustomFields.Any())
|
|
{
|
|
foreach (var customField in gameManifest.CustomFields)
|
|
{
|
|
script.AddVariable(customField.Name, customField.Value);
|
|
}
|
|
}
|
|
|
|
var extractionPath = Path.Combine(GameClient.GetMetadataDirectoryPath(installDirectory, redistributableId), "Files");
|
|
|
|
script.UseWorkingDirectory(extractionPath);
|
|
script.UseFile(path);
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
var handled = await RunScriptExternallyAsync(script);
|
|
|
|
if (!handled)
|
|
result = await script.ExecuteAsync<int>();
|
|
}
|
|
else
|
|
{
|
|
logger?.LogTrace("No name change script found");
|
|
}
|
|
|
|
op.Complete();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Ran into an unexpected error when attempting to run a Name Change script");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Games
|
|
public async Task<int> RunInstallScriptAsync(string installDirectory, Guid gameId)
|
|
{
|
|
int result = default;
|
|
|
|
try
|
|
{
|
|
var manifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Game>(installDirectory, gameId);
|
|
var path = ScriptHelper.GetScriptFilePath(installDirectory, gameId, Enums.ScriptType.Install);
|
|
|
|
using (var op = logger.BeginOperation("Executing install script"))
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.Install);
|
|
|
|
script.AddVariable("InstallDirectory", installDirectory);
|
|
script.AddVariable("GameManifest", manifest);
|
|
script.AddVariable("DefaultInstallDirectory", settingsProvider.CurrentValue.Games.InstallDirectories.FirstOrDefault());
|
|
script.AddVariable("ServerAddress", connectionClient.GetServerAddress());
|
|
|
|
if (manifest.CustomFields != null && manifest.CustomFields.Any())
|
|
{
|
|
foreach (var customField in manifest.CustomFields)
|
|
{
|
|
script.AddVariable(customField.Name, customField.Value);
|
|
}
|
|
}
|
|
|
|
script.UseFile(path);
|
|
|
|
try
|
|
{
|
|
op.Enrich("InstallDirectory", installDirectory)
|
|
.Enrich("ManifestPath", ManifestHelper.GetPath(installDirectory, gameId))
|
|
.Enrich("ScriptPath", path)
|
|
.Enrich("GameTitle", manifest.Title)
|
|
.Enrich("GameId", manifest.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
var handled = await RunScriptExternallyAsync(script);
|
|
|
|
if (!handled)
|
|
result = await script.ExecuteAsync<int>();
|
|
}
|
|
else
|
|
{
|
|
logger?.LogTrace("No install script found for game");
|
|
}
|
|
|
|
op.Complete();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Ran into an unexpected error when attempting to run an Install script");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> RunUninstallScriptAsync(string installDirectory, Guid gameId)
|
|
{
|
|
int result = default;
|
|
|
|
try
|
|
{
|
|
var manifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Game>(installDirectory, gameId);
|
|
var path = ScriptHelper.GetScriptFilePath(installDirectory, gameId, Enums.ScriptType.Uninstall);
|
|
|
|
using (var op = logger.BeginOperation("Executing uninstall script"))
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.Uninstall);
|
|
|
|
script.AddVariable("InstallDirectory", installDirectory);
|
|
script.AddVariable("GameManifest", manifest);
|
|
script.AddVariable("DefaultInstallDirectory", settingsProvider.CurrentValue.Games.InstallDirectories.FirstOrDefault());
|
|
script.AddVariable("ServerAddress", connectionClient.GetServerAddress());
|
|
|
|
if (manifest.CustomFields != null && manifest.CustomFields.Any())
|
|
{
|
|
foreach (var customField in manifest.CustomFields)
|
|
{
|
|
script.AddVariable(customField.Name, customField.Value);
|
|
}
|
|
}
|
|
|
|
script.UseFile(path);
|
|
|
|
try
|
|
{
|
|
op.Enrich("InstallDirectory", installDirectory)
|
|
.Enrich("ManifestPath", ManifestHelper.GetPath(installDirectory, gameId))
|
|
.Enrich("ScriptPath", path)
|
|
.Enrich("GameTitle", manifest.Title)
|
|
.Enrich("GameId", manifest.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
var handled = await RunScriptExternallyAsync(script);
|
|
|
|
if (!handled)
|
|
result = await script.ExecuteAsync<int>();
|
|
}
|
|
else
|
|
{
|
|
logger?.LogTrace("No uninstall script found");
|
|
}
|
|
|
|
op.Complete();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Ran into an unexpected error when attempting to get an Uninstall script");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> RunBeforeStartScriptAsync(string installDirectory, Guid gameId)
|
|
{
|
|
int result = default;
|
|
|
|
try
|
|
{
|
|
var manifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Game>(installDirectory, gameId);
|
|
var path = ScriptHelper.GetScriptFilePath(installDirectory, gameId, Enums.ScriptType.BeforeStart);
|
|
|
|
using (var op = logger.BeginOperation("Executing before start script"))
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.BeforeStart);
|
|
var playerAlias = await GameClient.GetPlayerAliasAsync(installDirectory, gameId);
|
|
|
|
script.AddVariable("InstallDirectory", installDirectory);
|
|
script.AddVariable("GameManifest", manifest);
|
|
script.AddVariable("DefaultInstallDirectory", settingsProvider.CurrentValue.Games.InstallDirectories.FirstOrDefault());
|
|
script.AddVariable("ServerAddress", connectionClient.GetServerAddress());
|
|
script.AddVariable("PlayerAlias", playerAlias);
|
|
|
|
if (manifest.CustomFields != null && manifest.CustomFields.Any())
|
|
{
|
|
foreach (var customField in manifest.CustomFields)
|
|
{
|
|
script.AddVariable(customField.Name, customField.Value);
|
|
}
|
|
}
|
|
|
|
script.UseFile(path);
|
|
|
|
try
|
|
{
|
|
op.Enrich("InstallDirectory", installDirectory)
|
|
.Enrich("ManifestPath", ManifestHelper.GetPath(installDirectory, gameId))
|
|
.Enrich("ScriptPath", path)
|
|
.Enrich("PlayerAlias", playerAlias)
|
|
.Enrich("GameTitle", manifest.Title)
|
|
.Enrich("GameId", manifest.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
var handled = await RunScriptExternallyAsync(script);
|
|
|
|
if (!handled)
|
|
result = await script.ExecuteAsync<int>();
|
|
}
|
|
else
|
|
{
|
|
logger?.LogTrace("No before start script found");
|
|
}
|
|
|
|
op.Complete();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Ran into an unexpected error when attempting to run a Before Start script");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> RunAfterStopScriptAsync(string installDirectory, Guid gameId)
|
|
{
|
|
int result = default;
|
|
|
|
try
|
|
{
|
|
var manifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Game>(installDirectory, gameId);
|
|
var path = ScriptHelper.GetScriptFilePath(installDirectory, gameId, Enums.ScriptType.AfterStop);
|
|
|
|
using (var op = logger.BeginOperation("Executing after stop script"))
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.AfterStop);
|
|
|
|
script.AddVariable("InstallDirectory", installDirectory);
|
|
script.AddVariable("GameManifest", manifest);
|
|
script.AddVariable("DefaultInstallDirectory", settingsProvider.CurrentValue.Games.InstallDirectories.FirstOrDefault());
|
|
script.AddVariable("ServerAddress", connectionClient.GetServerAddress());
|
|
script.AddVariable("PlayerAlias", GameClient.GetPlayerAlias(installDirectory, gameId));
|
|
|
|
if (manifest.CustomFields != null && manifest.CustomFields.Any())
|
|
{
|
|
foreach (var customField in manifest.CustomFields)
|
|
{
|
|
script.AddVariable(customField.Name, customField.Value);
|
|
}
|
|
}
|
|
|
|
script.UseFile(path);
|
|
|
|
try
|
|
{
|
|
op.Enrich("InstallDirectory", installDirectory)
|
|
.Enrich("ManifestPath", ManifestHelper.GetPath(installDirectory, gameId))
|
|
.Enrich("ScriptPath", path)
|
|
.Enrich("GameTitle", manifest.Title)
|
|
.Enrich("GameId", manifest.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
var handled = await RunScriptExternallyAsync(script);
|
|
|
|
if (!handled)
|
|
result = await script.ExecuteAsync<int>();
|
|
}
|
|
else
|
|
{
|
|
logger?.LogTrace("No after stop script found");
|
|
}
|
|
|
|
op.Complete();
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Ran into an unexpected error when attempting to run an After Stop script");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> RunNameChangeScriptAsync(string installDirectory, Guid gameId, string newName)
|
|
{
|
|
int result = default;
|
|
|
|
try
|
|
{
|
|
var path = ScriptHelper.GetScriptFilePath(installDirectory, gameId, Enums.ScriptType.NameChange);
|
|
var manifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Game>(installDirectory, gameId);
|
|
|
|
using (var op = logger.BeginOperation("Executing name change script"))
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
var oldName = await GameClient.GetPlayerAliasAsync(installDirectory, gameId);
|
|
|
|
if (oldName == newName)
|
|
oldName = string.Empty;
|
|
|
|
if (!string.IsNullOrWhiteSpace(oldName))
|
|
logger?.LogTrace("Old Name: {OldName}", oldName);
|
|
|
|
logger?.LogTrace("New Name: {NewName}", newName);
|
|
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.NameChange);
|
|
|
|
script.AddVariable("InstallDirectory", installDirectory);
|
|
script.AddVariable("GameManifest", manifest);
|
|
script.AddVariable("DefaultInstallDirectory", settingsProvider.CurrentValue.Games.InstallDirectories.FirstOrDefault());
|
|
script.AddVariable("ServerAddress", connectionClient.GetServerAddress());
|
|
script.AddVariable("OldPlayerAlias", oldName);
|
|
script.AddVariable("NewPlayerAlias", newName);
|
|
|
|
if (manifest.CustomFields != null && manifest.CustomFields.Any())
|
|
{
|
|
foreach (var customField in manifest.CustomFields)
|
|
{
|
|
script.AddVariable(customField.Name, customField.Value);
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
op.Enrich("InstallDirectory", installDirectory)
|
|
.Enrich("ManifestPath", ManifestHelper.GetPath(installDirectory, gameId))
|
|
.Enrich("ScriptPath", path)
|
|
.Enrich("OldPlayerAlias", oldName)
|
|
.Enrich("NewPlayerAlias", newName)
|
|
.Enrich("GameTitle", manifest.Title)
|
|
.Enrich("GameId", manifest.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
script.UseFile(path);
|
|
|
|
GameClient.UpdatePlayerAlias(installDirectory, gameId, newName);
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
var handled = await RunScriptExternallyAsync(script);
|
|
|
|
if (!handled)
|
|
result = await script.ExecuteAsync<int>();
|
|
}
|
|
else
|
|
{
|
|
logger?.LogTrace("No name change script found");
|
|
}
|
|
|
|
op.Complete();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Ran into an unexpected error when attempting to run a Name Change script");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> RunKeyChangeScriptAsync(string installDirectory, Guid gameId, string key)
|
|
{
|
|
int result = default;
|
|
|
|
try
|
|
{
|
|
var path = ScriptHelper.GetScriptFilePath(installDirectory, gameId, Enums.ScriptType.KeyChange);
|
|
var manifest = await ManifestHelper.ReadAsync<SDK.Models.Manifest.Game>(installDirectory, gameId);
|
|
|
|
using (var op = logger.BeginOperation("Executing key change script"))
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.KeyChange);
|
|
|
|
logger?.LogTrace("New key is {Key}", key);
|
|
|
|
script.AddVariable("InstallDirectory", installDirectory);
|
|
script.AddVariable("GameManifest", manifest);
|
|
script.AddVariable("DefaultInstallDirectory", settingsProvider.CurrentValue.Games.InstallDirectories.FirstOrDefault());
|
|
script.AddVariable("ServerAddress", connectionClient.GetServerAddress());
|
|
script.AddVariable("AllocatedKey", key);
|
|
|
|
if (manifest.CustomFields != null && manifest.CustomFields.Any())
|
|
{
|
|
foreach (var customField in manifest.CustomFields)
|
|
{
|
|
script.AddVariable(customField.Name, customField.Value);
|
|
}
|
|
}
|
|
|
|
script.UseFile(path);
|
|
|
|
try
|
|
{
|
|
op.Enrich("InstallDirectory", installDirectory)
|
|
.Enrich("ManifestPath", ManifestHelper.GetPath(installDirectory, gameId))
|
|
.Enrich("ScriptPath", path)
|
|
.Enrich("AllocatedKey", key)
|
|
.Enrich("GameTitle", manifest.Title)
|
|
.Enrich("GameId", manifest.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
await GameClient.UpdateCurrentKeyAsync(installDirectory, gameId, key);
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
var handled = await RunScriptExternallyAsync(script);
|
|
|
|
if (!handled)
|
|
result = await script.ExecuteAsync<int>();
|
|
}
|
|
else
|
|
{
|
|
logger?.LogTrace("No key change script found");
|
|
}
|
|
|
|
op.Complete();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Ran into an unexpected error when attempting to run a Key Change script");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<Package> RunPackageScriptAsync(Script packageScript, Game game)
|
|
{
|
|
try
|
|
{
|
|
using (var op = logger.BeginOperation("Executing game package script"))
|
|
{
|
|
var script = powerShellScriptFactory.Create(Enums.ScriptType.Package);
|
|
|
|
script.AddVariable("Game", game);
|
|
|
|
script.UseInline(packageScript.Contents);
|
|
|
|
try
|
|
{
|
|
op
|
|
.Enrich("GameId", game.Id)
|
|
.Enrich("GameTitle", game.Title)
|
|
.Enrich("ScriptId", packageScript.Id)
|
|
.Enrich("ScriptName", packageScript.Name);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not enrich logs");
|
|
}
|
|
|
|
if (Debug)
|
|
script.EnableDebug();
|
|
|
|
return await script.ExecuteAsync<Package>();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex, "Could not execute game package script");
|
|
}
|
|
|
|
return null;
|
|
}
|
|
#endregion
|
|
|
|
private async Task<bool> RunScriptExternallyAsync(PowerShellScript script)
|
|
{
|
|
var scriptRunners = serviceProvider.GetServices<IScriptInterceptor>();
|
|
|
|
foreach (var scriptRunner in scriptRunners)
|
|
{
|
|
if (await scriptRunner.ExecuteAsync(script))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|