From dbd98a09c5501c25aa5e7e74853142fffeb7ebd7 Mon Sep 17 00:00:00 2001 From: Westin Miller Date: Thu, 17 Aug 2017 17:32:08 -0700 Subject: [PATCH] Early initialization for Torch Client. - Assembly resolution - SE installation directory locating Dependency manager with automatic sorting and resolution - Drop in replacement for the system currently in TorchBase Shared binary directory for all Torch projects --- Torch.API/Torch.API.csproj | 8 +- Torch.Client/Program.cs | 157 ++++++++++++++++++- Torch.Client/Torch.Client.csproj | 26 +-- Torch.Client/TorchAssemblyResolver.cs | 88 +++++++++++ Torch.Client/TorchClient.cs | 88 +++++++---- Torch.Client/TorchClientConfig.cs | 32 ++++ Torch.Server/Torch.Server.csproj | 17 +- Torch/Managers/DependencyManager.cs | 217 ++++++++++++++++++++++++++ Torch/Managers/Manager.cs | 18 +++ Torch/Torch.csproj | 14 +- Torch/TorchBase.cs | 32 ++-- 11 files changed, 613 insertions(+), 84 deletions(-) create mode 100644 Torch.Client/TorchAssemblyResolver.cs create mode 100644 Torch.Client/TorchClientConfig.cs create mode 100644 Torch/Managers/DependencyManager.cs diff --git a/Torch.API/Torch.API.csproj b/Torch.API/Torch.API.csproj index c10adf2..d2e5c59 100644 --- a/Torch.API/Torch.API.csproj +++ b/Torch.API/Torch.API.csproj @@ -2,8 +2,6 @@ - Debug - AnyCPU {FBA5D932-6254-4A1E-BAF4-E229FA94E3C2} Library Properties @@ -15,7 +13,7 @@ true - bin\x64\Debug\ + $(SolutionDir)\bin\x64\Debug\ DEBUG;TRACE full x64 @@ -23,14 +21,14 @@ MinimumRecommendedRules.ruleset - bin\x64\Release\ + $(SolutionDir)\bin\x64\Release\ TRACE true pdbonly x64 prompt MinimumRecommendedRules.ruleset - bin\x64\Release\Torch.API.xml + $(SolutionDir)\bin\x64\Release\Torch.API.xml diff --git a/Torch.Client/Program.cs b/Torch.Client/Program.cs index 1bb555a..7fca9b0 100644 --- a/Torch.Client/Program.cs +++ b/Torch.Client/Program.cs @@ -1,17 +1,166 @@ using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; using System.Windows; +using System.Windows.Forms; using NLog; +using MessageBox = System.Windows.MessageBox; namespace Torch.Client { public static class Program { + public const string SpaceEngineersBinaries = "Bin64"; + private static string _spaceEngInstallAlias = null; + public static string SpaceEngineersInstallAlias + { + get + { + // ReSharper disable once ConvertIfStatementToNullCoalescingExpression + if (_spaceEngInstallAlias == null) + { + // ReSharper disable once AssignNullToNotNullAttribute + _spaceEngInstallAlias = Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "SpaceEngineersAlias"); + } + return _spaceEngInstallAlias; + } + } + + private static readonly string[] _steamInstallDirectories = new[] { + @"C:\Program Files\Steam\", @"C:\Program Files (x86)\Steam\" + }; + private const string _steamSpaceEngineersDirectory = @"steamapps\common\SpaceEngineers\"; + private const string _spaceEngineersVerifyFile = SpaceEngineersBinaries + @"\SpaceEngineers.exe"; + + public const string ConfigName = "Torch.cfg"; + private static Logger _log = LogManager.GetLogger("Torch"); +#if DEBUG + [DllImport("kernel32.dll")] + private static extern void AllocConsole(); + [DllImport("kernel32.dll")] + private static extern void FreeConsole(); +#endif public static void Main(string[] args) { - AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; +#if DEBUG + try + { + AllocConsole(); +#endif + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + // Early config: Resolve SE install directory. + if (!File.Exists(Path.Combine(SpaceEngineersInstallAlias, _spaceEngineersVerifyFile))) + SetupSpaceEngInstallAlias(); + + using (new TorchAssemblyResolver(Path.Combine(SpaceEngineersInstallAlias, SpaceEngineersBinaries))) + { + RunClient(); + } +#if DEBUG + } + finally + { + FreeConsole(); + } +#endif + } + + private static void SetupSpaceEngInstallAlias() + { + string spaceEngineersDirectory = null; + foreach (string steamDir in _steamInstallDirectories) + { + spaceEngineersDirectory = Path.Combine(steamDir, _steamSpaceEngineersDirectory); + if (File.Exists(Path.Combine(spaceEngineersDirectory, _spaceEngineersVerifyFile))) + { + _log.Debug("Found Space Engineers in {0}", spaceEngineersDirectory); + break; + } + _log.Debug("Couldn't find Space Engineers in {0}", spaceEngineersDirectory); + } + if (spaceEngineersDirectory == null) + { + var dialog = new System.Windows.Forms.FolderBrowserDialog + { + Description = "Please select the SpaceEngineers installation folder" + }; + do + { + if (dialog.ShowDialog() != DialogResult.OK) + { + var ex = new FileNotFoundException("Unable to find the Space Engineers install directory, aborting"); + _log.Fatal(ex); + LogManager.Flush(); + throw ex; + } + spaceEngineersDirectory = dialog.SelectedPath; + if (File.Exists(Path.Combine(spaceEngineersDirectory, _spaceEngineersVerifyFile))) + break; + if (MessageBox.Show( + $"Unable to find {0} in {1}. Are you sure it's the Space Engineers install directory?", + "Invalid Space Engineers Directory", MessageBoxButton.YesNo) == MessageBoxResult.Yes) + break; + } while (true); // Repeat until they confirm. + } + if (!JunctionLink(SpaceEngineersInstallAlias, spaceEngineersDirectory)) + { + var ex = new IOException($"Failed to create junction link {SpaceEngineersInstallAlias} => {spaceEngineersDirectory}. Aborting."); + _log.Fatal(ex); + LogManager.Flush(); + throw ex; + } + string junctionVerify = Path.Combine(SpaceEngineersInstallAlias, _spaceEngineersVerifyFile); + if (!File.Exists(junctionVerify)) + { + var ex = new FileNotFoundException($"Junction link is not working. File {junctionVerify} does not exist"); + _log.Fatal(ex); + LogManager.Flush(); + throw ex; + } + } + + private static bool JunctionLink(string linkName, string targetDir) + { + var junctionLinkProc = new ProcessStartInfo("cmd.exe", $"/c mklink /J \"{linkName}\" \"{targetDir}\"") + { + WorkingDirectory = Directory.GetCurrentDirectory(), + UseShellExecute = false, + RedirectStandardOutput = true, + StandardOutputEncoding = Encoding.ASCII + }; + Process cmd = Process.Start(junctionLinkProc); + // ReSharper disable once PossibleNullReferenceException + while (!cmd.HasExited) + { + string line = cmd.StandardOutput.ReadLine(); + if (!string.IsNullOrWhiteSpace(line)) + _log.Info(line); + Thread.Sleep(100); + } + if (cmd.ExitCode != 0) + _log.Error("Unable to create junction link {0} => {1}", linkName, targetDir); + return cmd.ExitCode == 0; + } + + private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + var ex = (Exception)e.ExceptionObject; + _log.Error(ex); + LogManager.Flush(); + MessageBox.Show(ex.StackTrace, ex.Message); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void RunClient() + { var client = new TorchClient(); try @@ -27,11 +176,5 @@ namespace Torch.Client client.Start(); } - - private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) - { - var ex = (Exception)e.ExceptionObject; - MessageBox.Show(ex.StackTrace, ex.Message); - } } } \ No newline at end of file diff --git a/Torch.Client/Torch.Client.csproj b/Torch.Client/Torch.Client.csproj index 66d3145..d6054c8 100644 --- a/Torch.Client/Torch.Client.csproj +++ b/Torch.Client/Torch.Client.csproj @@ -2,8 +2,6 @@ - Debug - AnyCPU {E36DF745-260B-4956-A2E8-09F08B2E7161} WinExe Properties @@ -18,7 +16,7 @@ true - bin\x64\Debug\ + $(SolutionDir)\bin\x64\Debug\ DEBUG;TRACE full x64 @@ -27,7 +25,7 @@ true - bin\x64\Release\ + $(SolutionDir)\bin\x64\Release\ TRACE true pdbonly @@ -35,7 +33,7 @@ prompt MinimumRecommendedRules.ruleset true - bin\x64\Release\Torch.Client.xml + $(SolutionDir)\bin\x64\Release\Torch.Client.xml torchicon.ico @@ -48,6 +46,7 @@ False ..\GameBinaries\Sandbox.Common.dll + False ..\GameBinaries\Sandbox.Game.dll @@ -64,6 +63,7 @@ + @@ -81,6 +81,10 @@ ..\GameBinaries\VRage.Game.dll False + + ..\GameBinaries\VRage.Game.XmlSerializers.dll + False + False ..\GameBinaries\VRage.Input.dll @@ -104,7 +108,8 @@ False - ..\..\..\..\..\..\..\steamcmd\steamapps\common\SpaceEngineersDedicatedServer\DedicatedServer64\VRage.Steam.dll + ..\GameBinaries\VRage.Steam.dll + False @@ -117,7 +122,9 @@ True + + @@ -147,12 +154,12 @@ {fba5d932-6254-4a1e-baf4-e229fa94e3c2} Torch.API - True + False {7E01635C-3B67-472E-BCD6-C5539564F214} Torch - True + False @@ -169,7 +176,8 @@ - copy "$(SolutionDir)NLog.config" "$(TargetDir)" + copy "$(SolutionDir)NLog.config" "$(TargetDir)" +