New system for resolving binaries

This commit is contained in:
Westin Miller
2017-10-04 21:40:42 -07:00
parent c14b8ed23a
commit d709bf68dd
4 changed files with 71 additions and 8 deletions

View File

@@ -27,7 +27,6 @@ login anonymous
app_update 298740
quit";
private TorchAssemblyResolver _resolver;
private TorchConfig _config;
private TorchServer _server;
private string _basePath;
@@ -50,7 +49,6 @@ quit";
if (!args.Contains("-noupdate"))
RunSteamCmd();
_resolver = new TorchAssemblyResolver(Path.Combine(_basePath, "DedicatedServer64"));
_config = InitConfig();
if (!_config.Parse(args))
return false;
@@ -94,8 +92,6 @@ quit";
}
else
_server.Start();
_resolver?.Dispose();
}
private TorchConfig InitConfig()

View File

@@ -44,13 +44,16 @@ namespace Torch.Server
var binDir = Path.Combine(workingDir, "DedicatedServer64");
Directory.SetCurrentDirectory(workingDir);
if (!TorchLauncher.IsTorchWrapped())
{
TorchLauncher.Launch(Assembly.GetEntryAssembly().FullName,args, binDir);
return;
}
if (!Environment.UserInteractive)
{
using (var service = new TorchService())
using (new TorchAssemblyResolver(binDir))
{
ServiceBase.Run(service);
}
return;
}

View File

@@ -215,6 +215,7 @@
<Compile Include="SteamService.cs" />
<Compile Include="TorchPluginBase.cs" />
<Compile Include="Session\TorchSession.cs" />
<Compile Include="Utils\TorchLauncher.cs" />
<Compile Include="ViewModels\ModViewModel.cs" />
<Compile Include="Collections\MTObservableCollection.cs" />
<Compile Include="Extensions\MyPlayerCollectionExtensions.cs" />

View File

@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Torch.API;
namespace Torch.Utils
{
public class TorchLauncher
{
private const string TorchKey = "TorchWrapper";
public static bool IsTorchWrapped()
{
return AppDomain.CurrentDomain.GetData(TorchKey) != null;
}
public static void Launch(string entryPoint, string[] args, params string[] binaryPaths)
{
if (IsTorchWrapped())
throw new Exception("Can't wrap torch twice");
string exePath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)?.ToLower().Replace('/', '\\');
if (exePath == null)
throw new ArgumentException("Unable to determine executing assembly's path");
var allPaths = new HashSet<string> { exePath };
foreach (string other in binaryPaths)
allPaths.Add(other.ToLower().Replace('/', '\\'));
var path = new StringBuilder(allPaths.First());
foreach (string other in binaryPaths)
{
if (path.Length > other.Length)
path.Remove(other.Length, path.Length - other.Length);
for (var i = 0; i < path.Length; i++)
if (path[i] != other[i])
{
path.Remove(i, path.Length - i);
break;
}
}
AppDomain.CurrentDomain.AppendPrivatePath(String.Join(Path.PathSeparator.ToString(), allPaths));
AppDomain.CurrentDomain.SetData(TorchKey, true);
AppDomain.CurrentDomain.ExecuteAssemblyByName(entryPoint, args);
return;
// this would be way better but HAVOK IS UNMANAGED :clang:
// exclude application base from probing
var setup = new AppDomainSetup
{
ApplicationBase = path.ToString(),
PrivateBinPathProbe = "",
PrivateBinPath = string.Join(";", allPaths)
};
AppDomain domain = AppDomain.CreateDomain($"TorchDomain-{Assembly.GetEntryAssembly().GetName().Name}-{new Random().Next():X}", null, setup);
domain.SetData(TorchKey, true);
domain.ExecuteAssemblyByName(entryPoint, args);
AppDomain.Unload(domain);
}
}
}