Skip to content

Commit

Permalink
Added: Experimental Support for Relative Paths in Application Configs
Browse files Browse the repository at this point in the history
  • Loading branch information
Sewer56 committed Feb 23, 2022
1 parent 15307b7 commit 50afede
Show file tree
Hide file tree
Showing 16 changed files with 66 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public interface IApplicationConfigV1

/// <summary>
/// The location of the main executable of the application.
/// This can be either specified relative to the folder in which the config is contained in or as an absolute path.
/// </summary>
string AppLocation { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<RepositoryUrl>https://github.com/Reloaded-Project/Reloaded-II</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<Version>2.0.0</Version>
<Version>2.1.0</Version>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Platforms>AnyCPU</Platforms>
<NoWarn>1701;1702;1591</NoWarn>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public MakeShortcutCommand(PathTuple<ApplicationConfig>? config, IIconConverter
public bool CanExecute(object? parameter)
{
if (_config != null)
return File.Exists(_config.Config.AppLocation);
return File.Exists(ApplicationConfig.GetAbsoluteAppLocation(_config));

return false;
}
Expand All @@ -45,9 +45,10 @@ public void Execute(object? parameter)
var loaderConfig = IoC.Get<LoaderConfig>();
var shell = (IShellLink) new ShellLink();

var appLocation = ApplicationConfig.GetAbsoluteAppLocation(_config);
shell.SetDescription($"Launch {_config?.Config.AppName} via Reloaded II");
shell.SetPath($"\"{loaderConfig.LauncherPath}\"");
shell.SetArguments($"{Constants.ParameterLaunch} \"{_config?.Config.AppLocation}\"");
shell.SetArguments($"{Constants.ParameterLaunch} \"{appLocation}\"");
shell.SetWorkingDirectory(Path.GetDirectoryName(loaderConfig.LauncherPath)!);

if (_config != null)
Expand All @@ -64,7 +65,7 @@ public void Execute(object? parameter)
}
else
{
shell.SetIconLocation(_config.Config.AppLocation, 0);
shell.SetIconLocation(appLocation, 0);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public QueryCommunityIndexCommand(PathTuple<ApplicationConfig> application)
}

/// <inheritdoc />
public bool CanExecute(object? parameter) => File.Exists(_application.Config.AppLocation);
public bool CanExecute(object? parameter) => File.Exists(ApplicationConfig.GetAbsoluteAppLocation(_application));

/// <inheritdoc />
public async void Execute(object? parameter) => await ExecuteAsync();
Expand All @@ -43,7 +43,7 @@ public QueryCommunityIndexCommand(PathTuple<ApplicationConfig> application)
public async Task ExecuteAsync()
{
var config = _application.Config;
await using var fileStream = new FileStream(config.AppLocation, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 524288);
await using var fileStream = new FileStream(ApplicationConfig.GetAbsoluteAppLocation(_application), FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 524288);
var indexApi = new IndexApi();
var index = await indexApi.GetIndexAsync();
var hash = Hashing.ToString(await xxHash64.ComputeHashAsync(fileStream));
Expand Down Expand Up @@ -75,7 +75,7 @@ public async Task ExecuteAsync()
/// <param name="pathTuple">The mod to apply the config to.</param>
public static void ApplyIndexEntry(AppItem indexApp, PathTuple<ApplicationConfig> pathTuple)
{
using var fileStream = new FileStream(pathTuple.Config.AppLocation, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 524288);
using var fileStream = new FileStream(ApplicationConfig.GetAbsoluteAppLocation(pathTuple), FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 524288);
var hash = Hashing.ToString(xxHash64.ComputeHash(fileStream));
ApplyIndexEntry(indexApp, pathTuple, hash);
}
Expand Down Expand Up @@ -106,7 +106,8 @@ public static void ApplyIndexEntry(AppItem indexApp, PathTuple<ApplicationConfig
Actions.ShowAddAppHashMismatchDialog(viewModel);
}

if (indexApp.TryGetError(Path.GetDirectoryName(pathTuple.Config.AppLocation)!, out var errors))
var appLocation = ApplicationConfig.GetAbsoluteAppLocation(pathTuple);
if (indexApp.TryGetError(Path.GetDirectoryName(appLocation)!, out var errors))
{
var viewModel = new AddApplicationWarningDialogViewModel(errors);
Actions.ShowApplicationWarningDialog(viewModel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private string SelectEXEFile()
var dialog = new VistaOpenFileDialog();
dialog.Title = Resources.AddAppExecutableTitle.Get();
dialog.Filter = $"{Resources.AddAppExecutableFilter.Get()} (*.exe)|*.exe";
dialog.FileName = Application.Config.AppLocation;
dialog.FileName = ApplicationConfig.GetAbsoluteAppLocation(Application);

if ((bool)dialog.ShowDialog()!)
return dialog.FileName;
Expand All @@ -196,7 +196,6 @@ private string SelectJsonFile()
var dialog = new VistaOpenFileDialog();
dialog.Title = Resources.AddAppRepoTestJsonSelectTitle.Get();
dialog.Filter = $"{Resources.AddAppRepoTestJsonSelectFilter.Get()} (*.json)|*.json";
dialog.FileName = Application.Config.AppLocation;

if ((bool)dialog.ShowDialog()!)
return dialog.FileName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public ApplicationViewModel(PathTuple<ApplicationConfig> tuple, ModConfigService
MakeShortcutCommand = new MakeShortcutCommand(tuple, Launcher.Lib.Lib.IconConverter);

IoC.Kernel.Rebind<ApplicationViewModel>().ToConstant(this);
_instanceTracker = new ApplicationInstanceTracker(tuple.Config.AppLocation);
_instanceTracker = new ApplicationInstanceTracker(ApplicationConfig.GetAbsoluteAppLocation(tuple));
_modConfigService.Items.CollectionChanged += OnGetModifications;
_instanceTracker.OnProcessesChanged += OnProcessesChanged;

Expand Down
3 changes: 2 additions & 1 deletion source/Reloaded.Mod.Launcher.Lib/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ private static void LaunchApplicationAndExit(string applicationToLaunch)
_commandLineArguments.TryGetValue(Constants.ParameterArguments, out var arguments);
arguments ??= "";
applicationToLaunch = Path.GetFullPath(applicationToLaunch);
var application = ApplicationConfig.GetAllApplications(IoC.Get<LoaderConfig>().ApplicationConfigDirectory).FirstOrDefault(x => Path.GetFullPath(x.Config.AppLocation) == applicationToLaunch);

var application = ApplicationConfig.GetAllApplications(IoC.Get<LoaderConfig>().ApplicationConfigDirectory).FirstOrDefault(x => ApplicationConfig.GetAbsoluteAppLocation(x) == applicationToLaunch);
if (application != null)
arguments = $"{arguments} {application.Config.AppArguments}";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private void BuildInitialProcesses(CancellationToken token = default)
public static bool GetAllProcesses(out IEnumerable<Process> processes)
{
var applications = ApplicationConfig.GetAllApplications();
var trackers = applications.Select(x => new ApplicationInstanceTracker(x.Config.AppLocation));
var trackers = applications.Select(x => new ApplicationInstanceTracker(ApplicationConfig.GetAbsoluteAppLocation(x)));
processes = trackers.SelectMany(x => x.GetProcesses().ReloadedProcesses);

return processes.Any();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Runtime.InteropServices;
using Reloaded.Mod.Launcher.Lib.Static;
using Reloaded.Mod.Loader.IO.Config;
using Reloaded.Mod.Loader.IO.Structs;

namespace Reloaded.Mod.Launcher.Lib.Utility;

Expand Down Expand Up @@ -39,9 +40,9 @@ public static ApplicationLauncher FromLocationAndArguments(string location, stri
/// <summary>
/// Creates an <see cref="ApplicationLauncher"/> from an application config.
/// </summary>
public static ApplicationLauncher FromApplicationConfig(ApplicationConfig config)
public static ApplicationLauncher FromApplicationConfig(PathTuple<ApplicationConfig> config)
{
return FromLocationAndArguments($"{config.AppLocation}", $"{config.AppArguments}");
return FromLocationAndArguments($"{ApplicationConfig.GetAbsoluteAppLocation(config)}", $"{config.Config.AppArguments}");
}

/// <summary>
Expand Down
16 changes: 9 additions & 7 deletions source/Reloaded.Mod.Launcher.Lib/Utility/AsiLoaderDeployer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ public bool Is64Bit(string filePath)
/// </summary>
public bool CanDeploy()
{
if (!File.Exists(Application.Config.AppLocation))
var appLocation = ApplicationConfig.GetAbsoluteAppLocation(Application);
if (!File.Exists(appLocation))
return false;

using var peParser = new BasicPeParser(Application.Config.AppLocation);
using var peParser = new BasicPeParser(appLocation);

try
{
Expand All @@ -67,8 +68,9 @@ public void DeployAsiLoader(out string? asiLoaderPath, out string bootstrapperPa
if (alreadyHasAsiPlugins)
return;

using var peParser = new BasicPeParser(Application.Config.AppLocation);
var appDirectory = Path.GetDirectoryName(Application.Config.AppLocation);
var appLocation = ApplicationConfig.GetAbsoluteAppLocation(Application);
using var peParser = new BasicPeParser(appLocation);
var appDirectory = Path.GetDirectoryName(appLocation);
var dllName = GetFirstSupportedDllFile(peParser);
asiLoaderPath = Path.Combine(appDirectory!, dllName!);
ExtractAsiLoader(asiLoaderPath, !peParser.Is32BitHeader);
Expand All @@ -91,7 +93,7 @@ public string GetBootstrapperInstallPath(out bool alreadyHasAsiPlugins)
/// </summary>
public string GetBootstrapperDllPath()
{
return Is64Bit(Application.Config.AppLocation)
return Is64Bit(ApplicationConfig.GetAbsoluteAppLocation(Application))
? IoC.Get<LoaderConfig>().Bootstrapper64Path
: IoC.Get<LoaderConfig>().Bootstrapper32Path;
}
Expand All @@ -102,7 +104,7 @@ public string GetBootstrapperDllPath()
/// </summary>
private bool AreAnyAsiPluginsInstalled(out string? modPath)
{
var appDirectory = Path.GetDirectoryName(Application.Config.AppLocation);
var appDirectory = Path.GetDirectoryName(ApplicationConfig.GetAbsoluteAppLocation(Application));
foreach (var directory in AsiCommonDirectories)
{
var directoryPath = Path.Combine(appDirectory!, directory);
Expand Down Expand Up @@ -136,7 +138,7 @@ private string GetBootstrapperInstallFolder(out bool alreadyHasAsiPlugins)
return installPath!;
}

var appDirectory = Path.GetDirectoryName(Application.Config.AppLocation);
var appDirectory = Path.GetDirectoryName(ApplicationConfig.GetAbsoluteAppLocation(Application));
var pluginDirectory = Path.Combine(appDirectory!, AsiCommonDirectories[0]);
return pluginDirectory;
}
Expand Down
3 changes: 2 additions & 1 deletion source/Reloaded.Mod.Launcher.Lib/Utility/AutoInjector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Diagnostics;
using System.Linq;
using Reloaded.Mod.Launcher.Lib.Utility.Interfaces;
using Reloaded.Mod.Loader.IO.Config;
using Reloaded.Mod.Loader.IO.Services;

namespace Reloaded.Mod.Launcher.Lib.Utility;
Expand Down Expand Up @@ -30,7 +31,7 @@ private void ProcessWatcherOnOnNewProcess(Process newProcess)
try
{
string fullPath = newProcess.GetExecutablePath();
var config = _configService.Items.FirstOrDefault(x => string.Equals(x.Config.AppLocation, fullPath, StringComparison.OrdinalIgnoreCase));
var config = _configService.Items.FirstOrDefault(x => string.Equals(ApplicationConfig.GetAbsoluteAppLocation(x), fullPath, StringComparison.OrdinalIgnoreCase));
if (config != null && config.Config.AutoInject)
{
var appInjector = new ApplicationInjector(newProcess);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,11 @@ private ImageSource GetImageForAppConfig(PathTuple<ApplicationConfig> applicatio
}

// Otherwise extract new icon from executable.
if (File.Exists(applicationConfig.Config.AppLocation))
var appLocation = ApplicationConfig.GetAbsoluteAppLocation(applicationConfig);
if (File.Exists(appLocation))
{
// Else make new from icon.
using Icon ico = Icon.ExtractAssociatedIcon(applicationConfig.Config.AppLocation);
using Icon ico = Icon.ExtractAssociatedIcon(appLocation);

// Extract to config set location.
BitmapSource bitmapImage = Imaging.CreateBitmapSourceFromHIcon(ico.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ private async void LaunchApplication_PreviewMouseDown(object sender, MouseButton
ViewModel.EnforceModCompatibility();
await Setup.CheckForMissingModDependenciesAsync();

var appConfig = ViewModel.ApplicationTuple.Config;
var launcher = ApplicationLauncher.FromApplicationConfig(appConfig);
var appTuple = ViewModel.ApplicationTuple;
var launcher = ApplicationLauncher.FromApplicationConfig(appTuple);

if (!Environment.IsWine || (Environment.IsWine && CompatibilityDialogs.WineShowLaunchDialog()))
launcher.Start();
Expand Down
28 changes: 28 additions & 0 deletions source/Reloaded.Mod.Loader.IO/Config/ApplicationConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,34 @@ public static List<BooleanGenericTuple<PathTuple<ModConfig>>> GetAllMods(IApplic
return totalModList;
}

/// <summary>
/// Converts the relative or absolute application location to a full path.
/// </summary>
/// <returns>The full path to the app location.</returns>
public static string GetAbsoluteAppLocation(PathTuple<ApplicationConfig> config)
{
var location = config.Config.AppLocation;
var basePath = Path.GetDirectoryName(config.Path)!;
string finalPath;

// Specific for windows paths starting on \ - they need the drive added to them.
// I constructed this piece like this for possible Mono support.
if (!Path.IsPathRooted(location) || "\\".Equals(Path.GetPathRoot(location)))
{
if (location.StartsWith(Path.DirectorySeparatorChar))
finalPath = Path.Combine(Path.GetPathRoot(basePath)!, location.TrimStart(Path.DirectorySeparatorChar));
else
finalPath = Path.Combine(basePath, location);
}
else
{
finalPath = location;
}

// Resolves any internal "..\" to get the true full path.
return Path.GetFullPath(finalPath);
}

/*
---------
Overrides
Expand Down
4 changes: 2 additions & 2 deletions source/Reloaded.Mod.Loader/Loader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,12 @@ private IApplicationConfig FindThisApplication()
foreach (var configuration in configurations)
{
var application = configuration.Config;
var appLocation = application.AppLocation;
var appLocation = ApplicationConfig.GetAbsoluteAppLocation(configuration);

if (string.IsNullOrEmpty(appLocation))
continue;

var fullAppLocation = NormalizePath(application.AppLocation);
var fullAppLocation = NormalizePath(appLocation);
if (fullAppLocation.Equals(fullPath, StringComparison.OrdinalIgnoreCase))
return application;
}
Expand Down
2 changes: 1 addition & 1 deletion source/Tools/Reloaded.Community.Tool/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private static void CreateTemplate(CreateTemplateOptions createTemplate)
AppId = appById.Config.AppId,
AppName = appById.Config.AppName,
AppStatus = Status.Ok,
Hash = Hashing.ToString(xxHash64.ComputeHash(File.ReadAllBytes(appById.Config.AppLocation))),
Hash = Hashing.ToString(xxHash64.ComputeHash(File.ReadAllBytes(ApplicationConfig.GetAbsoluteAppLocation(appById)))),
GameBananaId = config.GameId
});
}
Expand Down

0 comments on commit 50afede

Please sign in to comment.