New system for resolving binaries
This commit is contained in:
@@ -26,8 +26,7 @@ namespace Torch.Server
|
|||||||
login anonymous
|
login anonymous
|
||||||
app_update 298740
|
app_update 298740
|
||||||
quit";
|
quit";
|
||||||
|
|
||||||
private TorchAssemblyResolver _resolver;
|
|
||||||
private TorchConfig _config;
|
private TorchConfig _config;
|
||||||
private TorchServer _server;
|
private TorchServer _server;
|
||||||
private string _basePath;
|
private string _basePath;
|
||||||
@@ -50,7 +49,6 @@ quit";
|
|||||||
if (!args.Contains("-noupdate"))
|
if (!args.Contains("-noupdate"))
|
||||||
RunSteamCmd();
|
RunSteamCmd();
|
||||||
|
|
||||||
_resolver = new TorchAssemblyResolver(Path.Combine(_basePath, "DedicatedServer64"));
|
|
||||||
_config = InitConfig();
|
_config = InitConfig();
|
||||||
if (!_config.Parse(args))
|
if (!_config.Parse(args))
|
||||||
return false;
|
return false;
|
||||||
@@ -94,8 +92,6 @@ quit";
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
_server.Start();
|
_server.Start();
|
||||||
|
|
||||||
_resolver?.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TorchConfig InitConfig()
|
private TorchConfig InitConfig()
|
||||||
|
@@ -44,13 +44,16 @@ namespace Torch.Server
|
|||||||
var binDir = Path.Combine(workingDir, "DedicatedServer64");
|
var binDir = Path.Combine(workingDir, "DedicatedServer64");
|
||||||
Directory.SetCurrentDirectory(workingDir);
|
Directory.SetCurrentDirectory(workingDir);
|
||||||
|
|
||||||
|
if (!TorchLauncher.IsTorchWrapped())
|
||||||
|
{
|
||||||
|
TorchLauncher.Launch(Assembly.GetEntryAssembly().FullName,args, binDir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Environment.UserInteractive)
|
if (!Environment.UserInteractive)
|
||||||
{
|
{
|
||||||
using (var service = new TorchService())
|
using (var service = new TorchService())
|
||||||
using (new TorchAssemblyResolver(binDir))
|
|
||||||
{
|
|
||||||
ServiceBase.Run(service);
|
ServiceBase.Run(service);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -215,6 +215,7 @@
|
|||||||
<Compile Include="SteamService.cs" />
|
<Compile Include="SteamService.cs" />
|
||||||
<Compile Include="TorchPluginBase.cs" />
|
<Compile Include="TorchPluginBase.cs" />
|
||||||
<Compile Include="Session\TorchSession.cs" />
|
<Compile Include="Session\TorchSession.cs" />
|
||||||
|
<Compile Include="Utils\TorchLauncher.cs" />
|
||||||
<Compile Include="ViewModels\ModViewModel.cs" />
|
<Compile Include="ViewModels\ModViewModel.cs" />
|
||||||
<Compile Include="Collections\MTObservableCollection.cs" />
|
<Compile Include="Collections\MTObservableCollection.cs" />
|
||||||
<Compile Include="Extensions\MyPlayerCollectionExtensions.cs" />
|
<Compile Include="Extensions\MyPlayerCollectionExtensions.cs" />
|
||||||
|
63
Torch/Utils/TorchLauncher.cs
Normal file
63
Torch/Utils/TorchLauncher.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user