Skip to content

Commit

Permalink
including my custom apphost.exe in the repo with AmdPowerXpressReques…
Browse files Browse the repository at this point in the history
…tHighPerformance and NvOptimusEnablement - need to figure out how to get the csproj to use it when publishing, manually replacing for now

added DW2MC_DISABLE_GH_UPDATE_CHECK as env var option

made SharpDX device patching more extensive

started signing assemblies

added actual SharpDX libs instead of refs

moved some init around in AppDomainManager

added a GAC resolver to StartUp to help the right assemblies load
  • Loading branch information
Tyler-IN committed Apr 1, 2022
1 parent 1f058c6 commit 9dfe64b
Show file tree
Hide file tree
Showing 20 changed files with 157 additions and 23 deletions.
7 changes: 6 additions & 1 deletion DW2Net6Win/DW2Net6Win.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@

<SignAssembly>true</SignAssembly>

<AssemblyOriginatorKeyFile>DW2MC.snk</AssemblyOriginatorKeyFile>
<!--
<PublishSingleFile>true</PublishSingleFile>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
-->

<AssemblyOriginatorKeyFile>..\DW2MC.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

<ItemGroup>
Expand Down
25 changes: 22 additions & 3 deletions DW2Net6Win/PatchSharpDx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using Device = SharpDX.Direct3D11.Device;
using DeviceChild = SharpDX.Direct3D11.DeviceChild;

namespace DW2Net6Win;

Expand Down Expand Up @@ -62,15 +63,32 @@ public static void Apply()
{
var prefix = new HarmonyMethod(Method(() => PrefixEnterLockInstance(null!)));
var postfix = new HarmonyMethod(Method(() => PostfixExitLockInstance(null!)));
var types = new[] { typeof(Device), typeof(DeviceContext) };
var types = new[]
{
typeof(Device),
typeof(SharpDX.Direct3D11.Device1),
typeof(SharpDX.Direct3D11.Device2),
typeof(SharpDX.Direct3D11.Device3),
typeof(SharpDX.Direct3D11.Device4),
typeof(Device5),
typeof(DeviceContext),
typeof(DeviceContext1),
typeof(DeviceContext2),
typeof(DeviceContext3),
typeof(DeviceContext4),
typeof(Device11On12),
typeof(DeviceChild)
};
foreach (var t in types)
foreach (var m in t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.Where(m => !m.IsStatic && !m.IsConstructor && !m.IsGenericMethod && !m.IsAbstract && !m.IsVirtual))
foreach (var m in t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
if (m.IsStatic || m.IsConstructor || m.IsGenericMethod || m.IsAbstract || m.IsVirtual) continue;
try { Program.Harmony.Patch(m, prefix, postfix); }
catch
{
/* oh no! anyway... */
}
}
}

[SuppressMessage("ReSharper", "InconsistentNaming")]
Expand All @@ -80,6 +98,7 @@ public static bool PrefixEnterLockInstance(object __instance)
Monitor.Enter(__instance);
return true;
}

[SuppressMessage("ReSharper", "InconsistentNaming")]
public static void PostfixExitLockInstance(object __instance)
=> Monitor.Exit(__instance);
Expand Down
14 changes: 10 additions & 4 deletions DW2Net6Win/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ static Program()
ProfileOptimization.StartProfile("DW2-" + hc.ToString("X8"));
}

private static readonly Version V4 = new(4, 0, 0, 0);
private static readonly Version V6 = new(6, 0, 0, 0);

[UsedImplicitly]
Expand Down Expand Up @@ -92,15 +91,22 @@ public static int Main(string[] args)
var an = new AssemblyName(eventArgs.Name);
var name = an.Name!;
if (name.StartsWith("System.") && (an.Version?.Equals(V4) ?? false))
var isSystem = name.StartsWith("System.");
if (isSystem)
{
var v = an.Version;
if (v is not null && v.CompareTo(V6) >= 0)
return null;
an.Version = V6;
return Assembly.Load(an);
}
var dll = name + ".dll";
var p = Path.Combine(Environment.CurrentDirectory, name + ".dll");
var p = Path.Combine(Environment.CurrentDirectory, dll);
if (File.Exists(p))
if (File.Exists(dll))
return Assembly.LoadFile(p);
return null;
Expand Down
Binary file added DW2Net6Win/apphost.exe
Binary file not shown.
3 changes: 3 additions & 0 deletions DistantWorlds2.ModLoader.ModManager/GitHubUpdateCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ public bool IsNewVersionAvailable

private async Task<bool> PerformCheckAsync()
{
if (Environment.GetEnvironmentVariable("DW2MC_DISABLE_GH_UPDATE_CHECK") == "1")
return false;

// background unobserved socket exceptions break things
// see DW2Net6Win's Program.SpinUpSockets
//if (IsTieredPGOEnabled || Debugger.IsAttached)
Expand Down
38 changes: 26 additions & 12 deletions DistantWorlds2.ModLoader/AppDomainManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Reflection;
using System.Runtime;
using System.Security;
using System.Security.Policy;
using System.Text;
using JetBrains.Annotations;

Expand All @@ -29,6 +30,12 @@ private static int QuickStringHash(int hc, string? str)
return hc;
}


private static readonly Type[] TypeRefs =
{
typeof(ModLoader), typeof(ModManager), typeof(Patches)
};

static AppDomainManager()
{
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
Expand All @@ -37,21 +44,28 @@ static AppDomainManager()
var ct = Thread.CurrentThread;
ct.CurrentCulture = CultureInfo.InvariantCulture;
ct.CurrentUICulture = CultureInfo.InvariantCulture;

if (Debugger.IsAttached) return;
var hc = 17;
hc = QuickStringHash(hc, Dw2Version);
hc = QuickStringHash(hc, ModLoaderVersion);
ProfileOptimization.SetProfileRoot("tmp");
ProfileOptimization.StartProfile("DW2-" + hc.ToString("X8"));
}

private static readonly Type[] TypeRefs =
{
typeof(ModLoader), typeof(ModManager), typeof(Patches)
};
public override void InitializeNewDomain(AppDomainSetup appDomainInfo)
=> StartUp.InitializeModLoader();
{
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;

var ct = Thread.CurrentThread;
ct.CurrentCulture = CultureInfo.InvariantCulture;
ct.CurrentUICulture = CultureInfo.InvariantCulture;

if (!Debugger.IsAttached)
{
var hc = 17;
hc = QuickStringHash(hc, Dw2Version);
hc = QuickStringHash(hc, ModLoaderVersion);
ProfileOptimization.SetProfileRoot("tmp");
ProfileOptimization.StartProfile("DW2-" + hc.ToString("X8"));
}

StartUp.InitializeModLoader();
}

public override System.Threading.HostExecutionContextManager HostExecutionContextManager { get; }
= new HostExecutionContextManager();
Expand Down
90 changes: 87 additions & 3 deletions DistantWorlds2.ModLoader/StartUp.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Text;
using System.Windows.Forms;
using HarmonyLib;
using JetBrains.Annotations;
using MonoMod.Utils;
using Xenko.Core.MicroThreading;
using Xenko.Engine;

Expand All @@ -17,6 +20,47 @@ public static class StartUp
private static bool _initialized;
private static bool _started;


private static readonly string GacBaseDir = Environment.ExpandEnvironmentVariables(@"%WINDIR%\Microsoft.NET\assembly");


private static Assembly? GacAssemblyResolver(object _, ResolveEventArgs args)
{
try
{
var an = new AssemblyName(args.Name);
var name = an.Name!;

var isSystem = name.StartsWith("System.");

if (isSystem)
{
var v = an.Version;

var token = an.GetPublicKeyToken();
var sb = new StringBuilder(token.Length * 2);
foreach (var b in token)
{
sb.Append((b >> 4).ToString("x"));
sb.Append((b & 0xF).ToString("x"));
}
var dll = name + ".dll";
var path = Path.Combine(GacBaseDir, "GAC_MSIL", name, $"v4.0_{v.ToString(4)}__{sb}", dll);
if (File.Exists(path))
return Assembly.LoadFile(path);
path = Path.Combine(GacBaseDir, "GAC_64", name, $"v4.0_{v.ToString(4)}__{sb}", dll);
if (File.Exists(path))
return Assembly.LoadFile(path);
Console.Error.WriteLine($"Could not resolve in GAC: {an}");
}
}
catch (Exception ex)
{
ModLoader.OnUnhandledException(ExceptionDispatchInfo.Capture(ex));
}
return null;
}

public static void StartModLoader()
{
if (_started) return;
Expand All @@ -26,17 +70,16 @@ public static void StartModLoader()
ct.CurrentCulture = CultureInfo.InvariantCulture;
ct.CurrentUICulture = CultureInfo.InvariantCulture;


Console.CancelKeyPress += (_, args) => {
args.Cancel = true;
ConsoleHelper.TryDetachFromConsoleWindow();
};

ConsoleHelper.ConsoleControlEvent += _ => {
ConsoleHelper.TryDetachFromConsoleWindow();
return true;
};

var debug = Environment.GetEnvironmentVariable("DW2MC_DEBUG");

if (debug is not null && debug is not "")
Expand Down Expand Up @@ -105,6 +148,7 @@ public static void StartModLoader()
.UnblockFile(new Uri(typeof(StartUp).Assembly.EscapedCodeBase).LocalPath);
ModLoader.Patches = new Patches();
ModLoader.ModManager = new ModManager();

}
private static string GetCodeBaseLocalPath(Assembly asm)
{
Expand Down Expand Up @@ -154,8 +198,48 @@ public static void InitializeModLoader()
if (_initialized) return;
_initialized = true;

SetUpGacAssemblyResolver();

AppDomain.CurrentDomain.AssemblyLoad += AssemblyLoadHandler;
}
private static void SetUpGacAssemblyResolver()
{
var dom = AppDomain.CurrentDomain;

try
{
var miAsmResolveEvent = typeof(AppDomain).GetMethod("OnAssemblyResolveEvent",
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
if (miAsmResolveEvent is not null)
{
var hmPrefixAsmResolverPatch =
new HarmonyMethod(ReflectionUtils<Assembly>.Method(a => PrefixAssemblyResolverPatch(ref a, null!, null!)));
new Harmony("DistantWorlds2.ModLoader").Patch(miAsmResolveEvent, hmPrefixAsmResolverPatch);
return;
}
}
catch (Exception ex)
{
Console.Error.WriteLine("Could not patch AppDomain.OnAssemblyResolveEvent! Using fallback event...");
ModLoader.OnUnhandledException(ExceptionDispatchInfo.Capture(ex));
}

try { dom.AssemblyResolve += GacAssemblyResolver; }
catch (Exception ex)
{
Console.Error.WriteLine("Could not use AppDomain.AssemblyResolve event!");
ModLoader.OnUnhandledException(ExceptionDispatchInfo.Capture(ex));
}

}
[SuppressMessage("ReSharper", "InconsistentNaming")]
public static bool PrefixAssemblyResolverPatch(ref Assembly __result, Assembly assembly, string assemblyFullName)
{
var asm = GacAssemblyResolver(null!, new(assemblyFullName, assembly));
if (asm is null) return true;
__result = asm;
return false;
}
private static void AssemblyLoadHandler(object sender, AssemblyLoadEventArgs args)
{
var asmName = args.LoadedAssembly.GetName();
Expand Down
1 change: 1 addition & 0 deletions Version.proj
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
<PackageProjectUrl>https://github.com/DW2MC/DW2ModLoader</PackageProjectUrl>
<PackageLicenseUrl>https://raw.githubusercontent.com/DW2MC/DW2ModLoader/main/LICENSE</PackageLicenseUrl>

<AssemblyOriginatorKeyFile>..\DW2MC.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
</Project>
2 changes: 2 additions & 0 deletions ref/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ These are only reference assemblies.
They contain no private metadata or code of any kind.

They only contain publicly visible symbols.

Except for the SharpDX libraries, they have weird COM stuff that gets linked.
Binary file modified ref/SharpDX.D3DCompiler.dll
Binary file not shown.
Binary file modified ref/SharpDX.DXGI.dll
Binary file not shown.
Binary file modified ref/SharpDX.Direct3D11.dll
Binary file not shown.
Binary file modified ref/SharpDX.Direct3D12.dll
Binary file not shown.
Binary file modified ref/SharpDX.Direct3D9.dll
Binary file not shown.
Binary file modified ref/SharpDX.DirectInput.dll
Binary file not shown.
Binary file modified ref/SharpDX.Mathematics.dll
Binary file not shown.
Binary file modified ref/SharpDX.MediaFoundation.dll
Binary file not shown.
Binary file modified ref/SharpDX.RawInput.dll
Binary file not shown.
Binary file modified ref/SharpDX.XInput.dll
Binary file not shown.
Binary file modified ref/SharpDX.dll
Binary file not shown.

0 comments on commit 9dfe64b

Please sign in to comment.