Files
sbox-public/engine/Sandbox.Tools/ToolAssemblyResolver.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

89 lines
1.9 KiB
C#

using Mono.Cecil;
using System;
using System.IO;
using System.Reflection;
using Sandbox;
namespace Tools
{
internal class ToolAssemblyResolver : IAssemblyResolver
{
private readonly DefaultAssemblyResolver _fallbackResolver = new();
public ToolAssemblyResolver()
{
var rootAsm = typeof( EngineLoop ).Assembly;
var asmDir = Path.GetDirectoryName( rootAsm.Location );
_fallbackResolver.AddSearchDirectory( asmDir );
}
private Dictionary<string, AssemblyDefinition> Loaded { get; } = new( StringComparer.OrdinalIgnoreCase );
public void Dispose()
{
foreach ( var (_, asmDef) in Loaded )
{
asmDef.Dispose();
}
Loaded.Clear();
}
private static string GetKey( Assembly asm )
{
return asm.GetName().Name;
}
public void AddAssembly( Assembly asm, TrustedBinaryStream stream )
{
var key = GetKey( asm );
if ( Loaded.Remove( key, out var asmDef ) )
{
asmDef.Dispose();
}
var oldPos = stream.Position;
try
{
var copy = new MemoryStream( new byte[stream.Length] );
stream.Seek( 0, SeekOrigin.Begin );
stream.CopyTo( copy );
copy.Seek( 0, SeekOrigin.Begin );
asmDef = AssemblyDefinition.ReadAssembly( copy, new ReaderParameters { AssemblyResolver = this } );
}
finally
{
stream.Seek( oldPos, SeekOrigin.Begin );
}
Loaded[key] = asmDef;
}
public void RemoveAssembly( Assembly asm )
{
var key = GetKey( asm );
if ( Loaded.Remove( key, out var asmDef ) )
{
asmDef.Dispose();
}
}
public AssemblyDefinition Resolve( AssemblyNameReference name )
{
return Loaded.TryGetValue( name.Name, out var asmDef ) ? asmDef : _fallbackResolver.Resolve( name );
}
public AssemblyDefinition Resolve( AssemblyNameReference name, ReaderParameters parameters )
{
return Loaded.TryGetValue( name.Name, out var asmDef ) ? asmDef : _fallbackResolver.Resolve( name, parameters );
}
}
}