diff --git a/Torch.Server/Initializer.cs b/Torch.Server/Initializer.cs
index e4fe99e..7da5757 100644
--- a/Torch.Server/Initializer.cs
+++ b/Torch.Server/Initializer.cs
@@ -26,8 +26,7 @@ namespace Torch.Server
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()
diff --git a/Torch.Server/Program.cs b/Torch.Server/Program.cs
index efcc40a..ec745b2 100644
--- a/Torch.Server/Program.cs
+++ b/Torch.Server/Program.cs
@@ -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;
}
diff --git a/Torch/Torch.csproj b/Torch/Torch.csproj
index 9d94c77..7bd9cb9 100644
--- a/Torch/Torch.csproj
+++ b/Torch/Torch.csproj
@@ -215,6 +215,7 @@
+
diff --git a/Torch/Utils/TorchLauncher.cs b/Torch/Utils/TorchLauncher.cs
new file mode 100644
index 0000000..39bcf77
--- /dev/null
+++ b/Torch/Utils/TorchLauncher.cs
@@ -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 { 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);
+ }
+ }
+}